Java 8 Lambda:比较器示例

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

1.典型Comparator例子。

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

2. 上面等效于下列Lambda表达式

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

1.不使用Lambda进行排序

下面是用年龄比较Developer对象的例子。 通常使用Collections.sort并传递一个匿名Comparator类,如下所示:

TestSorting.java

  1. import java.math.BigDecimal;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. import java.util.Comparator;
  5. import java.util.List;
  6. public class TestSorting {
  7. public static void main(String[] args) {
  8. List<Developer> listDevs = getDevelopers();
  9. System.out.println("Before Sort");
  10. for (Developer developer : listDevs) {
  11. System.out.println(developer);
  12. }
  13. //sort by age
  14. Collections.sort(listDevs, new Comparator<Developer>() {
  15. @Override
  16. public int compare(Developer o1, Developer o2) {
  17. return o1.getAge() - o2.getAge();
  18. }
  19. });
  20. System.out.println("After Sort");
  21. for (Developer developer : listDevs) {
  22. System.out.println(developer);
  23. }
  24. }
  25. private static List<Developer> getDevelopers() {
  26. List<Developer> result = new ArrayList<Developer>();
  27. result.add(new Developer("test", new BigDecimal("70000"), 33));
  28. result.add(new Developer("alvin", new BigDecimal("80000"), 20));
  29. result.add(new Developer("jason", new BigDecimal("100000"), 10));
  30. result.add(new Developer("iris", new BigDecimal("170000"), 55));
  31. return result;
  32. }
  33. }

输出:

  1. Before Sort
  2. Developer [name=test, salary=70000, age=33]
  3. Developer [name=alvin, salary=80000, age=20]
  4. Developer [name=jason, salary=100000, age=10]
  5. Developer [name=iris, salary=170000, age=55]
  6. After Sort
  7. Developer [name=jason, salary=100000, age=10]
  8. Developer [name=alvin, salary=80000, age=20]
  9. Developer [name=mkyong, salary=70000, age=33]
  10. Developer [name=iris, salary=170000, age=55]

当排序要求发生变化时,您只需传入另一个新的匿名Comparator类:

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

这种方式用起来很麻烦。

2.用Lambda排序

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

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

Lambda表达示例:

TestSorting.java

  1. import java.math.BigDecimal;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. public class TestSorting {
  5. public static void main(String[] args) {
  6. List<Developer> listDevs = getDevelopers();
  7. System.out.println("Before Sort");
  8. for (Developer developer : listDevs) {
  9. System.out.println(developer);
  10. }
  11. System.out.println("After Sort");
  12. //lambda here!
  13. listDevs.sort((Developer o1, Developer o2)->o1.getAge()-o2.getAge());
  14. //java 8 only, lambda also, to print the List
  15. listDevs.forEach((developer)->System.out.println(developer));
  16. }
  17. private static List<Developer> getDevelopers() {
  18. List<Developer> result = new ArrayList<Developer>();
  19. result.add(new Developer("test", new BigDecimal("70000"), 33));
  20. result.add(new Developer("alvin", new BigDecimal("80000"), 20));
  21. result.add(new Developer("jason", new BigDecimal("100000"), 10));
  22. result.add(new Developer("iris", new BigDecimal("170000"), 55));
  23. return result;
  24. }
  25. }

输出:

  1. Before Sort
  2. Developer [name=test, salary=70000, age=33]
  3. Developer [name=alvin, salary=80000, age=20]
  4. Developer [name=jason, salary=100000, age=10]
  5. Developer [name=iris, salary=170000, age=55]
  6. After Sort
  7. Developer [name=jason, salary=100000, age=10]
  8. Developer [name=alvin, salary=80000, age=20]
  9. Developer [name=mkyong, salary=70000, age=33]
  10. Developer [name=iris, salary=170000, age=55]

3.更多Lambda示例

3.1按年龄分类

  1. //sort by age
  2. Collections.sort(listDevs, new Comparator<Developer>() {
  3. @Override
  4. public int compare(Developer o1, Developer o2) {
  5. return o1.getAge() - o2.getAge();
  6. }
  7. });
  8. //lambda
  9. listDevs.sort((Developer o1, Developer o2)->o1.getAge()-o2.getAge());
  10. //lambda, valid, parameter type is optional
  11. listDevs.sort((o1, o2)->o1.getAge()-o2.getAge());

3.2按名称排序

  1. //sort by name
  2. Collections.sort(listDevs, new Comparator<Developer>() {
  3. @Override
  4. public int compare(Developer o1, Developer o2) {
  5. return o1.getName().compareTo(o2.getName());
  6. }
  7. });
  8. //lambda
  9. listDevs.sort((Developer o1, Developer o2)->o1.getName().compareTo(o2.getName()));
  10. //lambda
  11. listDevs.sort((o1, o2)->o1.getName().compareTo(o2.getName()));

3.3按工资排序

  1. //sort by salary
  2. Collections.sort(listDevs, new Comparator<Developer>() {
  3. @Override
  4. public int compare(Developer o1, Developer o2) {
  5. return o1.getSalary().compareTo(o2.getSalary());
  6. }
  7. });
  8. //lambda
  9. listDevs.sort((Developer o1, Developer o2)->o1.getSalary().compareTo(o2.getSalary()));
  10. //lambda
  11. listDevs.sort((o1, o2)->o1.getSalary().compareTo(o2.getSalary()));

3.4倒序。

3.4.1使用他们的薪水对List进行排序的Lambda表达式:

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

输出:

  1. Developer [name=mkyong, salary=70000, age=33]
  2. Developer [name=alvin, salary=80000, age=20]
  3. Developer [name=jason, salary=100000, age=10]
  4. Developer [name=iris, salary=170000, age=55]

3.4.2按照薪水倒序的Lambda表达式:

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

输出:

  1. Developer [name=iris, salary=170000, age=55]
  2. Developer [name=jason, salary=100000, age=10]
  3. Developer [name=alvin, salary=80000, age=20]
  4. Developer [name=mkyong, salary=70000, age=33]