Java:Lambda Comparator

原文地址:https://mkyong.com/java8/java-8-lambda-comparator-example/

在这个例子中,我将会展示如何使用Java 8 Lambda表达式去写一个Comparator来对List进行排序。

  1. 传统Comparator例子:

    1
    2
    3
    4
    5
    6
    Comparator<Developer> byName = new Comparator<Developer>() {
    @Override
    public int compare(Developer o1, Developer o2) {
    return o1.getName().compareTo(o2.getName());
    }
    };
  2. 等价的Lambda表达式

    1
    2
    Comparator<Developer> byName = 
    (Developer o1, Developer o2) -> o1.getName().compareTo(o2.getName());

不用Lambda排序

举个通过age属性对Developer对象进行排序的例子。通常,你使用Collections.sort然后传入匿名Comparator类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class TestSorting {
public static void main(String[] args) {
List<Developer> listDevs = getDevelopers();

System.out.println("Befor sort");
for(Developer developer:listDevs) {
System.out.println(developer);
}

//sort by age
Collections.sort(listDevs, new Comparator<Developer>() {
@Override
public int compare(Developer o1,Developer o2) {
return o1,getAge()-o2.getAge();
}
});

System.out.println("After Sort");
for(Developer developer:ListDevs) {
System.out.println(developer);
}
}

private static List<Developer> getDevelopers() {
List<Developer> result = new ArrayList<Developer>();

result.add(new Developer("mkyong", new BigDecimal("70000"),33));
result.add(new Developer("alvin", new BigDecimal("80000"),20));
result.add(new Developer("jason", new BigDecimal("100000"),10));
result.add(new Developer("iris", new BigDecimal("170000"),55));

return result;
}
}

输出:

1
2
3
4
5
6
7
8
9
10
11
Before Sort
Developer [name=mkyong, salary=7000, age=33]
Developer [name=alvin, salary=8000, age=20]
Developer [name=jason, salary=10000, age=10]
Developer [name=iris, salary=17000, age=55]

After Sort
Developer [name=jason, salary=10000, age=10]
Developer [name=alvin, salary=8000, age=20]
Developer [name=mkyong, salary=7000, age=33]
Developer [name=iris, salary=17000, age=55]

如果排序要求变了,你只需要传入另一个匿名Comparator类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//sort by age
Collections.sort(listDevs, new Comparator<Developer>() {
@Override
public int compare(Developer o1, Developer o2) {
return o1.getAge()-o2.getAge();
}
});
// sort by name
Collections.sort(listDevs, new Comparator<Developer>() {
@Override
public int compare(Developer o1, Developer o2) {
return o1.getName().compareTo(o2.getNmae());
}
});
//sort by salary
Collections.sort(listDevs, new Comparator<Developer>() {
@Override
public int compare(Developer o1, Developer o2) {
return o1.getSalary().compareTo(o2.getSlary());
}
});

这方法有效,但是你不觉得这样有点奇怪吗,因为你只想改变一行代码却创建了一个新的类。

用Lambda排序

在Java 8中,List接口直接支持sort方法,不需要再用Collections.sort

1
2
3
4
5
6
7
// Java 8 之后的List.sort()
listDevs.sort(new Comparator<Deceloper>() {
@Override
public int compare(Developer o1, Developer o2) {
return o2.getAge()-o1.getAge();
}
});

Lambda表达式例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class TestSorting {
public static void main(String[] args) {
List<Developer> listDevs = getDevelopers();

System.out.println("Before Sort");
for(Developer developer : listDevs) {
System.out.println(developer);
}
System.out.println("After Sort");
// lambda
listDevs.sort((Developer o1, Developer o2)->o1.getAge()-o2.getAge());
listDevs.forEach((developer)->System.out.println(developer));
}
private static List<Developer> getDevelopers() {
List<Developer> result = new ArrayList<Developer>();

result.add(new Developer("mkyong", new BigDecimal("70000"),33));
result.add(new Developer("alvin", new BigDecimal("80000"),20));
result.add(new Developer("jason", new BigDecimal("100000"),10));
result.add(new Developer("iris", new BigDecimal("170000"),55));

return result;
}

}

输出和前面的例子一样。

更多lambda的例子

Sort by age

1
2
3
4
5
6
7
8
9
10
11
// sort by age
Collections.sort(listDevs, new Comparator<Developer>() {
@Override
public int compare(Developer o1, Developer o2) {
return o1.getAge()-o2.getAge();
}
});
//lambda
listDevs.sort((Developer o1, Developer o2)->o1.getAge()-o2.getAge());
//同样有效的lambda,参数类型不是必须的
listDevs.sort((o1, o2)->o1.getAge()-o2.getAge());

Sort by Name

1
2
3
4
5
6
7
8
9
10
11
// sort by name
Collections.sort(listDevs, new Comparator<Developer>() {
@Override
public int compare(Developer o1, Developer o2) {
return o1.getName().compareTo(o2.getName());
}
});
//lambda
listDevs.sort((Developer o1, Developer o2)->o1.getName().compareTo(o2.getName()));
//同样有效的lambda,参数类型不是必须的
listDevs.sort((o1, o2)->o1.getName().compareTo(o2.getName()));

Sort by salary

1
2
3
4
5
6
7
8
9
10
11
//sort by salary
Collections.sort(listDevs, new Comparator<Developer>() {
@Override
public int compare(Developer o1, Developer o2) {
return o1.getSalary().compareTo(o2.getSalary());
}
});
//lambda
listDevs.sort((Developer o1, Developer o2)->o1.getSalary().compareTo(o2.getSalary()));
//同样有效的lambda,参数类型不是必须的
listDevs.sort((o1, o2)->o1.getSalary().compareTo(o2.getSalary()));

反向排序

1
2
Comparator<Developer> salaryComparator = (o1, o2)->o1.getSalary().compareTo(o2.getSalary());
listDevs.sort(salaryComparator.reversed());

个人理解就是把前面的正向排序的lambda表达式拆分城两部分,一部分是用lambda表达式把Comparator实现,另一部分则是把Comparator的对象作为参数传入sort方法,并且可以使用.reversed()


Q. What is Comparable and Comparator Interface in java?

Comparable and Comparator both are interfaces and can be used to sort collection elements.

Comparable Comparator
1) Comparable provides a single sorting sequence. In other words, we can sort the collection on the basis of a single element such as id, name, and price. The Comparator provides multiple sorting sequences. In other words, we can sort the collection on the basis of multiple elements such as id, name, and price etc.
2) Comparable affects the original class, i.e., the actual class is modified. Comparator doesn’t affect the original class, i.e., the actual class is not modified.
3) Comparable provides compareTo() method to sort elements. Comparator provides compare() method to sort elements.
4) Comparable is present in java.lang package. A Comparator is present in the java.util package.

5) We can sort the list elements of Comparable type by Collections.sort(List) method.|We can sort the list elements of Comparator type by Collections.sort(List, Comparator) method.|