亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java8怎么使用Lambda表達式進行比較

發布時間:2022-01-26 11:46:47 來源:億速云 閱讀:157 作者:柒染 欄目:開發技術

本篇文章為大家展示了Java8怎么使用Lambda表達式進行比較,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

在Java 8之前,對集合進行排序需要為排序中使用的比較器 Comparator 創建一個匿名內部類:

new Comparator<Human>() {
    @Override
    public int compare(Human h2, Human h3) {
        return h2.getName().compareTo(h3.getName());
    }
}

這僅用于對 Human 實體列表進行排序:

@Test
public void givenPreLambda_whenSortingEntitiesByName_thenCorrectlySorted() {
    List<Human> humans = Lists.newArrayList(
      new Human("Sarah", 10), 
      new Human("Jack", 12)
    );
    
    Collections.sort(humans, new Comparator<Human>() {
        @Override
        public int compare(Human h2, Human h3) {
            return h2.getName().compareTo(h3.getName());
        }
    });
    Assert.assertThat(humans.get(0), equalTo(new Human("Jack", 12)));
}

支持Lambda的基本排序

隨著Lambdas的引入,我們現在可以繞過匿名內部類,通過簡單的函數語義實現相同的結果:

(final Human h2, final Human h3) -> h2.getName().compareTo(h3.getName());

類似地,我們現在可以像以前一樣測試行為:

@Test
public void whenSortingEntitiesByName_thenCorrectlySorted() {
    List<Human> humans = Lists.newArrayList(
      new Human("Sarah", 10), 
      new Human("Jack", 12)
    );
    
    humans.sort(
      (Human h2, Human h3) -> h2.getName().compareTo(h3.getName()));
 
    assertThat(humans.get(0), equalTo(new Human("Jack", 12)));
}

注意,我們還使用添加到java中的新排序API。 java.util.List 使用Java8而不是舊集合列出 Collections.sort 。

無類型定義的基本排序

我們可以通過不指定類型定義來進一步簡化表達式;編譯器能夠自行推斷出以下各項:

(h2, h3) -> h2.getName().compareTo(h3.getName())

同樣,測試仍然非常相似:

@Test
public void 
  givenLambdaShortForm_whenSortingEntitiesByName_thenCorrectlySorted() {
    
    List<Human> humans = Lists.newArrayList(
      new Human("Sarah", 10), 
      new Human("Jack", 12)
    );
    
    humans.sort((h2, h3) -> h2.getName().compareTo(h3.getName()));
 
    assertThat(humans.get(0), equalTo(new Human("Jack", 12)));
}

使用引用靜態方法進行排序

接下來,我們將使用Lambda表達式和對靜態方法的引用來執行排序。

首先,我們將使用與 Comparator<Human> 對象中的 compare 方法完全相同的簽名來定義 CompareBynametEnable 方法:

public static int compareByNameThenAge(Human lhs, Human rhs) {
    if (lhs.name.equals(rhs.name)) {
        return Integer.compare(lhs.age, rhs.age);
    } else {
        return lhs.name.compareTo(rhs.name);
    }
}

然后我們要調用 humans.sort 使用此引用的排序方法:

humans.sort(Human::compareByNameThenAge);

最終結果是使用靜態方法作為比較器對集合進行工作排序:

@Test
public void 
  givenMethodDefinition_whenSortingEntitiesByNameThenAge_thenCorrectlySorted() {
    
    List<Human> humans = Lists.newArrayList(
      new Human("Sarah", 10), 
      new Human("Jack", 12)
    );
    
    humans.sort(Human::compareByNameThenAge);
    Assert.assertThat(humans.get(0), equalTo(new Human("Jack", 12)));
}

Sort Extracted Comparators

通過使用實例方法引用和比較器,我們甚至可以避免定義比較邏輯本身。比較方法,該方法基于該函數提取并創建可比較的。

我們將使用 getName() 來構建Lambda表達式并按名稱對列表進行排序:

@Test
public void 
  givenInstanceMethod_whenSortingEntitiesByName_thenCorrectlySorted() {
    
    List<Human> humans = Lists.newArrayList(
      new Human("Sarah", 10), 
      new Human("Jack", 12)
    );
    
    Collections.sort(
      humans, Comparator.comparing(Human::getName));
    assertThat(humans.get(0), equalTo(new Human("Jack", 12)));
}

反向排序

JDK 8還引入了一種輔助方法來反轉比較器。我們可以很快利用這一點來逆轉我們的排序:

@Test
public void whenSortingEntitiesByNameReversed_thenCorrectlySorted() {
    List<Human> humans = Lists.newArrayList(
      new Human("Sarah", 10), 
      new Human("Jack", 12)
    );
    
    Comparator<Human> comparator
      = (h2, h3) -> h2.getName().compareTo(h3.getName());
    
    humans.sort(comparator.reversed());
 
    Assert.assertThat(humans.get(0), equalTo(new Human("Sarah", 10)));
}

使用多個條件進行排序

比較lambda表達式不必如此簡單。我們還可以編寫更復雜的表達式,例如,先按名稱,然后按年齡對實體進行排序:

@Test
public void whenSortingEntitiesByNameThenAge_thenCorrectlySorted() {
    List<Human> humans = Lists.newArrayList(
      new Human("Sarah", 12), 
      new Human("Sarah", 10), 
      new Human("Zack", 12)
    );
    
    humans.sort((lhs, rhs) -> {
        if (lhs.getName().equals(rhs.getName())) {
            return Integer.compare(lhs.getAge(), rhs.getAge());
        } else {
            return lhs.getName().compareTo(rhs.getName());
        }
    });
    Assert.assertThat(humans.get(0), equalTo(new Human("Sarah", 10)));
}

使用多個條件排序-組合

同樣的比較邏輯,首先按名稱排序,然后按年齡排序,也可以通過新的composition支持來實現。

從JDK 8開始,我們現在可以將多個比較器鏈接在一起,以構建更復雜的比較邏輯:

@Test
public void 
  givenComposition_whenSortingEntitiesByNameThenAge_thenCorrectlySorted() {
    
    List<Human> humans = Lists.newArrayList(
      new Human("Sarah", 12), 
      new Human("Sarah", 10), 
      new Human("Zack", 12)
    );

    humans.sort(
      Comparator.comparing(Human::getName).thenComparing(Human::getAge)
    );
    
    Assert.assertThat(humans.get(0), equalTo(new Human("Sarah", 10)));
}

使用Stream.sorted()對列表進行排序

我們還可以使用Java 8的Stream sorted()API對集合進行排序。

我們可以使用自然排序以及比較器提供的排序對流進行排序。為此,我們有兩個sorted()API的重載變體:

  • sorted()&ndash;使用自然排序對流的元素進行排序;元素類必須實現可比較的接口。

  • sorted(Comparator<? super T> comparator)&ndash;基于Comparator實例對元素進行排序

讓我們看一個如何將sorted()方法用于自然排序的示例:

@Test
public final void 
  givenStreamNaturalOrdering_whenSortingEntitiesByName_thenCorrectlySorted() {
    List<String> letters = Lists.newArrayList("B", "A", "C");
	
    List<String> sortedLetters = letters.stream().sorted().collect(Collectors.toList());
    assertThat(sortedLetters.get(0), equalTo("A"));
}

現在,讓我們看看如何在 sorted() API中使用自定義比較器:

@Test
public final void 
  givenStreamCustomOrdering_whenSortingEntitiesByName_thenCorrectlySorted() {	
    List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
    Comparator<Human> nameComparator = (h2, h3) -> h2.getName().compareTo(h3.getName());
	
    List<Human> sortedHumans = 
      humans.stream().sorted(nameComparator).collect(Collectors.toList());
    assertThat(sortedHumans.get(0), equalTo(new Human("Jack", 12)));
}

如果使用比較器,我們可以進一步簡化上述示例。 Comparator.comparing() 方法:

@Test
public final void 
  givenStreamComparatorOrdering_whenSortingEntitiesByName_thenCorrectlySorted() {
    List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
 
    List<Human> sortedHumans = humans.stream()
      .sorted(Comparator.comparing(Human::getName))
      .collect(Collectors.toList());
      
    assertThat(sortedHumans.get(0), equalTo(new Human("Jack", 12)));
}

使用Stream.sorted()對列表進行反向排序

我們也可以使用 Stream.sorted() 對集合進行反向排序。

首先,讓我們看一個如何將sorted()方法與Comparator相結合的示例。reverseOrder()按與自然順序相反的順序對列表排序:

@Test
public final void 
  givenStreamNaturalOrdering_whenSortingEntitiesByNameReversed_thenCorrectlySorted() {
    List<String> letters = Lists.newArrayList("B", "A", "C");

    List<String> reverseSortedLetters = letters.stream()
      .sorted(Comparator.reverseOrder())
      .collect(Collectors.toList());
      
    assertThat(reverseSortedLetters.get(0), equalTo("C"));
}

現在讓我們看看如何使用sorted()方法和自定義比較器:

@Test
public final void 
  givenStreamCustomOrdering_whenSortingEntitiesByNameReversed_thenCorrectlySorted() {
    List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
    Comparator<Human> reverseNameComparator = 
      (h2, h3) -> h3.getName().compareTo(h2.getName());

    List<Human> reverseSortedHumans = humans.stream().sorted(reverseNameComparator)
      .collect(Collectors.toList());
    assertThat(reverseSortedHumans.get(0), equalTo(new Human("Sarah", 10)));
}

請注意,compareTo的調用是翻轉的,它負責反轉。

最后,讓我們使用比較器簡化上述示例。Comparator.comparing() 方法:

@Test
public final void 
  givenStreamComparatorOrdering_whenSortingEntitiesByNameReversed_thenCorrectlySorted() {
    List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));

    List<Human> reverseSortedHumans = humans.stream()
      .sorted(Comparator.comparing(Human::getName, Comparator.reverseOrder()))
      .collect(Collectors.toList());
    
    assertThat(reverseSortedHumans.get(0), equalTo(new Human("Sarah", 10)));
}

Null值

到目前為止,我們實現的比較器不能對包含空值的集合進行排序。也就是說,如果集合至少包含一個null元素,則sort方法會引發 NullPointerException :

@Test(expected = NullPointerException.class)
public void givenANullElement_whenSortingEntitiesByName_thenThrowsNPE() {
    List<Human> humans = Lists.newArrayList(null, new Human("Jack", 12));

    humans.sort((h2, h3) -> h2.getName().compareTo(h3.getName()));
}

最簡單的解決方案是在比較器實現中手動處理空值:

@Test
public void givenANullElement_whenSortingEntitiesByNameManually_thenMovesTheNullToLast() {
    List<Human> humans = Lists.newArrayList(null, new Human("Jack", 12), null);

    humans.sort((h2, h3) -> {
        if (h2 == null) {
            return h3 == null ? 0 : 1;
        }
        else if (h3 == null) {
            return -1;
        }
        return h2.getName().compareTo(h3.getName());
    });

    Assert.assertNotNull(humans.get(0));
    Assert.assertNull(humans.get(1));
    Assert.assertNull(humans.get(2));
}

在這里,我們將所有空元素推向集合的末尾。為此,比較器將null視為大于非null值。如果兩者都為空,則認為它們相等。

此外,我們可以將任何非空安全的比較器 Comparator.nullsLast() 方法,并獲得相同的結果:

@Test
public void givenANullElement_whenSortingEntitiesByName_thenMovesTheNullToLast() {
    List<Human> humans = Lists.newArrayList(null, new Human("Jack", 12), null);

    humans.sort(Comparator.nullsLast(Comparator.comparing(Human::getName)));

    Assert.assertNotNull(humans.get(0));
    Assert.assertNull(humans.get(1));
    Assert.assertNull(humans.get(2));
}

同樣,我們可以使用 Comparator.nullsFirst() 將null元素移到集合的開頭:

@Test
public void givenANullElement_whenSortingEntitiesByName_thenMovesTheNullToStart() {
    List<Human> humans = Lists.newArrayList(null, new Human("Jack", 12), null);

    humans.sort(Comparator.nullsFirst(Comparator.comparing(Human::getName)));

    Assert.assertNull(humans.get(0));
    Assert.assertNull(humans.get(1));
    Assert.assertNotNull(humans.get(2));
}

強烈建議使用 nullsFirst() 或 nullsLast() 修飾符,因為它們更靈活、可讀性更強。

上述內容就是Java8怎么使用Lambda表達式進行比較,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

体育| 资兴市| 莱州市| 仁布县| 宁蒗| 大埔区| 十堰市| 达拉特旗| 保德县| 迁西县| 资源县| 北辰区| 海丰县| 融水| 望江县| 武鸣县| 天祝| 亚东县| 建湖县| 自贡市| 安多县| 鹿泉市| 沂水县| 宁远县| 凤山县| 陆良县| 璧山县| 理塘县| 商水县| 云梦县| 陈巴尔虎旗| 龙山县| 绥芬河市| 姜堰市| 桦甸市| 贺兰县| 云安县| 遂昌县| 东丽区| 团风县| 两当县|