1. Overview
First, let's first define a simple entity class:
@Datapublicclass Human { private String name; privateint age; publicHuman() { super(); } publicHuman(finalfinalint age) { super(); this.name = name; this.age = age; }}
2. Basic sorting without using lambda expressions
Before Java 8, sort the collection to create an anonymous inner class for comparator to sort:
new Comparator<Human>() { @Override publicintcompare(Human h1, Human h2) { return h1.getName().compareTo(h2.getName()); }}
Simply use it to sort the list of human entities:
@Test Public void Test() {listnewarraylist(New Human("Sarah.",Ten),New Human("Jack", A)); Collections.Sort(Humans,NewComparator@Override Public int Compare(Human H1, Human H2) {returnH1.GetName().CompareTo(H2.GetName()); } }); Assert.Assertthat(Humans.Get(0),Equalto(New Human("Jack", A))); }
3. Basic sorting using lambda expressions
Based on the introduction of lambda expressions, we can now get the same results without using anonymous inner classes, using only simple and practical semantics.
(finalfinal Human h2) -> h1.getName().compareTo(h2.getName());
Similarly, we can now test its behavior as we did before:
@Test void test () {listnewarraylist (new human (, 10 ), new human (, 12 )); Humans. sort (Human H1, Human H2), H1. getname (). compareto (H2. getname ())); Assert. assertthat (Humans. get (0 ), equalto (new human (, 12 )));
Note: We also use the new sort API, which is added to java.util.list--instead of the old Collections.sort API in Java 8.
4. No basic ordering of type definitions (type definitions)
We further simplify the expression by not specifying the type definition-the compiler can make type judgments by itself:
(h1, h2) -> h1.getName().compareTo(h2.getName())
The tests are still similar:
@Test void test () {listnewarraylist (new human (, 10 ), new human (, 12 )); Humans. sort (H1, H2), H1. getname (). compareto (H2. getname ())); Assert. assertthat (Humans. get (0 ), equalto (new human (, 12 )));
5. Sort using a reference to a static method
Below we will use a lambda expression with a static method reference to sort.
First, we want to define the Comparebynamethenage method--This method has the comparator
publicstaticintcompareByNameThenAge(Human lhs, Human rhs) { if (lhs.name.equals(rhs.name)) { return lhs.age - rhs.age; else { return lhs.name.compareTo(rhs.name); }}
Now, we're going to use this reference to invoke the Humans.sort method:
humans.sort(Human::compareByNameThenAge);
The end result is a valid sorted collection that uses static methods as comparator:
@Testpublicvoidtest() { List<Human> humans = Lists.newArrayList(newHuman("Sarah"10newHuman("Jack"12)); humans.sort(Human::compareByNameThenAge); Assert.assertThat(humans.get(0equalTo(newHuman("Jack"12)));}
6. Sorting by extracting comparator
We can avoid defining comparison logic by using the reference and Comparator.comparing methods of the instance method-it extracts and creates a comparable based on that function.
We're going to use the GetName () Getter method to build a lambda expression and sort the list by name:
@Testpublicvoidtest() { List<Human> humans = Lists.newArrayList(newHuman("Sarah"10newHuman("Jack"12)); Collections.sort(humans, Comparator.comparing(Human::getName)); Assert.assertThat(humans.get(0equalTo(newHuman("Jack"12)));}
7. Reverse Sort
JDK 8 also provides a useful way to reverse Comparator (reverse Comparator)-we can quickly use it to reverse our sort:
@Test public void test () {list (new human ( "Sarah" , 10 ), new human (, 12 )); comparatorgetname (). compareto (H2. getname ()); Humans. sort (Comparator. reversed ()); Assert. assertthat (Humans. get (0 ), equalto (new human (, 10 )));
8. Multi-Conditional sorting
Lambda expressions that compare operations are not necessarily all that simple-we can also write more complex expressions, such as sorting the entities according to age based on the name:
@Test Public void Test() {listnewarraylist(New Human("Sarah.", A),New Human("Sarah.",Ten),New Human("Zack", A)); Humans.Sort(LHS, RHS), {if(LHS.GetName().equals(RHS.GetName())) {returnLhs.Getage()-RHS.Getage(); }Else{returnLhs.GetName().CompareTo(RHS.GetName()); } }); Assert.Assertthat(Humans.Get(0),Equalto(New Human("Sarah.",Ten)));}
9. Multi-conditional combination sorting
The same comparison logic--first sorted by name, followed by age--can also be achieved by comparator new combination support.
Starting with JDK 8, we can now chain together multiple comparator (chain together) to build more complex comparison logic:
@Test Public void Test() {listnewarraylist(New Human("Sarah.", A),New Human("Sarah.",Ten),New Human("Zack", A)); Humans.Sort(Comparator.Comparing(Human::getname).thencomparing(Human::getage)); Assert.Assertthat(Humans.Get(0),Equalto(New Human("Sarah.",Ten)));}
Reference: HTTP://WWW.BAELDUNG.COM/JAVA-8-SORT-LAMBDA
Java8 Sort Summary