当前位置:   article > 正文

Comparator.comparing比较排序_comparator comparing

comparator comparing

Java8 - 使用 Comparator.comparing 进行比较排序

使用外部比较器Comparator进行排序

当我们需要对集合的元素进行排序的时候,可以使用java.util.Comparator 创建一个比较器来进行排序。Comparator接口同样也是一个函数式接口,我们可以把使用lambda表达式。如下示例,

  1. package com.common;
  2. import java.util.*;
  3. import java.util.stream.Collectors;
  4. public class ComparatorTest {
  5. public static void main(String[] args) {
  6. Employee e1 = new Employee("John", 25, 3000, 9922001);
  7. Employee e2 = new Employee("Ace", 22, 2000, 5924001);
  8. Employee e3 = new Employee("Keith", 35, 4000, 3924401);
  9. List<Employee> employees = new ArrayList<>();
  10. employees.add(e1);
  11. employees.add(e2);
  12. employees.add(e3);
  13. /**
  14. * @SuppressWarnings({"unchecked", "rawtypes"})
  15. * default void sort(Comparator<? super E> c) {
  16. * Object[] a = this.toArray();
  17. * Arrays.sort(a, (Comparator) c);
  18. * ListIterator<E> i = this.listIterator();
  19. * for (Object e : a) {
  20. * i.next();
  21. * i.set((E) e);
  22. * }
  23. * }
  24. *
  25. * sort 对象接收一个 Comparator 函数式接口,可以传入一个lambda表达式
  26. */
  27. employees.sort((o1, o2) -> o1.getName().compareTo(o2.getName()));
  28. Collections.sort(employees, (o1, o2) -> o1.getName().compareTo(o2.getName()));
  29. employees.forEach(System.out::println);
  30. }
  31. }
  32. /**
  33. * [Employee(name=John, age=25, salary=3000.0, mobile=9922001),
  34. * Employee(name=Ace, age=22, salary=2000.0, mobile=5924001),
  35. * Employee(name=Keith, age=35, salary=4000.0, mobile=3924401)]
  36. */
  37. class Employee {
  38. String name;
  39. int age;
  40. double salary;
  41. long mobile;
  42. // constructors, getters & setters
  43. public Employee(String name, int age, double salary, long mobile) {
  44. this.name = name;
  45. this.age = age;
  46. this.salary = salary;
  47. this.mobile = mobile;
  48. }
  49. public String getName() {
  50. return name;
  51. }
  52. public void setName(String name) {
  53. this.name = name;
  54. }
  55. public int getAge() {
  56. return age;
  57. }
  58. public void setAge(int age) {
  59. this.age = age;
  60. }
  61. public double getSalary() {
  62. return salary;
  63. }
  64. public void setSalary(double salary) {
  65. this.salary = salary;
  66. }
  67. public long getMobile() {
  68. return mobile;
  69. }
  70. public void setMobile(long mobile) {
  71. this.mobile = mobile;
  72. }
  73. @Override
  74. public String toString() {
  75. final StringBuilder sb = new StringBuilder("Employee{");
  76. sb.append("name='").append(name).append('\'');
  77. sb.append(", age=").append(age);
  78. sb.append(", salary=").append(salary);
  79. sb.append(", mobile=").append(mobile);
  80. sb.append('}');
  81. return sb.toString();
  82. }
  83. }

 

使用 Comparator.comparing 进行排序

comparing 方法一

查看 Comparator 类内部实现,还有一个 comparing 方法,实现如下,

  1. public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
  2. Function<? super T, ? extends U> keyExtractor)
  3. {
  4. Objects.requireNonNull(keyExtractor);
  5. return (Comparator<T> & Serializable)
  6. (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
  7. }

其返回值是 (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2)); 一个lambda表达式,也就是一个Compator 。所以上面那个例子也可以改造成 如下,

  1. package com.common;
  2. import java.util.*;
  3. public class ComparatorTest {
  4. public static void main(String[] args) {
  5. Employee e1 = new Employee("John", 25, 3000, 9922001);
  6. Employee e2 = new Employee("Ace", 22, 2000, 5924001);
  7. Employee e3 = new Employee("Keith", 35, 4000, 3924401);
  8. List<Employee> employees = new ArrayList<>();
  9. employees.add(e1);
  10. employees.add(e2);
  11. employees.add(e3);
  12. /**
  13. * @SuppressWarnings({"unchecked", "rawtypes"})
  14. * default void sort(Comparator<? super E> c) {
  15. * Object[] a = this.toArray();
  16. * Arrays.sort(a, (Comparator) c);
  17. * ListIterator<E> i = this.listIterator();
  18. * for (Object e : a) {
  19. * i.next();
  20. * i.set((E) e);
  21. * }
  22. * }
  23. *
  24. * sort 对象接收一个 Comparator 函数式接口,可以传入一个lambda表达式
  25. */
  26. employees.sort((o1, o2) -> o1.getName().compareTo(o2.getName()));
  27. Collections.sort(employees, (o1, o2) -> o1.getName().compareTo(o2.getName()));
  28. employees.forEach(System.out::println);
  29. /**
  30. * Comparator.comparing 方法的使用
  31. *
  32. * comparing 方法接收一个 Function 函数式接口 ,通过一个 lambda 表达式传入
  33. *
  34. */
  35. employees.sort(Comparator.comparing(e -> e.getName()));
  36. /**
  37. * 该方法引用 Employee::getName 可以代替 lambda表达式
  38. */
  39. employees.sort(Comparator.comparing(Employee::getName));
  40. }
  41. }
  42. /**
  43. * [Employee(name=John, age=25, salary=3000.0, mobile=9922001),
  44. * Employee(name=Ace, age=22, salary=2000.0, mobile=5924001),
  45. * Employee(name=Keith, age=35, salary=4000.0, mobile=3924401)]
  46. */
  47. class Employee {
  48. String name;
  49. int age;
  50. double salary;
  51. long mobile;
  52. // constructors, getters & setters
  53. public Employee(String name, int age, double salary, long mobile) {
  54. this.name = name;
  55. this.age = age;
  56. this.salary = salary;
  57. this.mobile = mobile;
  58. }
  59. public String getName() {
  60. return name;
  61. }
  62. public void setName(String name) {
  63. this.name = name;
  64. }
  65. public int getAge() {
  66. return age;
  67. }
  68. public void setAge(int age) {
  69. this.age = age;
  70. }
  71. public double getSalary() {
  72. return salary;
  73. }
  74. public void setSalary(double salary) {
  75. this.salary = salary;
  76. }
  77. public long getMobile() {
  78. return mobile;
  79. }
  80. public void setMobile(long mobile) {
  81. this.mobile = mobile;
  82. }
  83. @Override
  84. public String toString() {
  85. final StringBuilder sb = new StringBuilder("Employee{");
  86. sb.append("name='").append(name).append('\'');
  87. sb.append(", age=").append(age);
  88. sb.append(", salary=").append(salary);
  89. sb.append(", mobile=").append(mobile);
  90. sb.append('}');
  91. return sb.toString();
  92. }
  93. }

 

comparing 方法二

  1. public static <T, U> Comparator<T> comparing(
  2. Function<? super T, ? extends U> keyExtractor,
  3. Comparator<? super U> keyComparator)
  4. {
  5. Objects.requireNonNull(keyExtractor);
  6. Objects.requireNonNull(keyComparator);
  7. return (Comparator<T> & Serializable)
  8. (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
  9. keyExtractor.apply(c2));
  10. }

和comparing 方法一不同的是 该方法多了一个参数 keyComparator ,keyComparator 是创建一个自定义的比较器。

  1. Collections.sort(employees, Comparator.comparing(
  2. Employee::getName, (s1, s2) -> {
  3. return s2.compareTo(s1);
  4. }));

 

使用 Comparator.reversed 进行排序

返回相反的排序规则,

  1. /**
  2. * 相反的排序规则
  3. */
  4. Collections.sort(employees, Comparator.comparing(Employee::getName).reversed());
  5. employees.forEach(System.out::println);

输出,

  1. Employee{name='Keith', age=35, salary=4000.0, mobile=3924401}
  2. Employee{name='John', age=25, salary=3000.0, mobile=9922001}
  3. Employee{name='Ace', age=22, salary=2000.0, mobile=5924001}

 

使用 Comparator.nullsFirst进行排序

当集合中存在null元素时,可以使用针对null友好的比较器,null元素排在集合的最前面

  1. employees.add(null); //插入一个null元素
  2. Collections.sort(employees, Comparator.nullsFirst(Comparator.comparing(Employee::getName)));
  3. employees.forEach(System.out::println);
  4. Collections.sort(employees, Comparator.nullsLast(Comparator.comparing(Employee::getName)));
  5. employees.forEach(System.out::println);

 

使用 Comparator.thenComparing 排序

首先使用 name 排序,紧接着在使用ege 排序,来看下使用效果

  1. Collections.sort(employees, Comparator.comparing(Employee::getAge).thenComparing(Employee::getName));
  2. employees.forEach(System.out::println);

 转载:https://my.oschina.net/xinxingegeya/blog/2046405

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/355136
推荐阅读
  

闽ICP备14008679号