电子商务网站的推广方式,手机怎么做优惠券网站,在线简历,做游戏必备的几个网站使用外部比较器Comparator进行排序
当我们需要对集合的元素进行排序的时候#xff0c;可以使用java.util.Comparator 创建一个比较器来进行排序。Comparator接口同样也是一个函数式接口#xff0c;我们可以把使用lambda表达式。如下示例#xff0c;
package com.common;im…使用外部比较器Comparator进行排序
当我们需要对集合的元素进行排序的时候可以使用java.util.Comparator 创建一个比较器来进行排序。Comparator接口同样也是一个函数式接口我们可以把使用lambda表达式。如下示例
package com.common;import java.util.*;
import java.util.stream.Collectors;public class ComparatorTest {public static void main(String[] args) {Employee e1 new Employee(John, 25, 3000, 9922001);Employee e2 new Employee(Ace, 22, 2000, 5924001);Employee e3 new Employee(Keith, 35, 4000, 3924401);ListEmployee employees new ArrayList();employees.add(e1);employees.add(e2);employees.add(e3);/*** SuppressWarnings({unchecked, rawtypes})* default void sort(Comparator? super E c) {* Object[] a this.toArray();* Arrays.sort(a, (Comparator) c);* ListIteratorE i this.listIterator();* for (Object e : a) {* i.next();* i.set((E) e);* }* }** sort 对象接收一个 Comparator 函数式接口可以传入一个lambda表达式*/employees.sort((o1, o2) - o1.getName().compareTo(o2.getName()));Collections.sort(employees, (o1, o2) - o1.getName().compareTo(o2.getName()));employees.forEach(System.out::println);}
}/*** [Employee(nameJohn, age25, salary3000.0, mobile9922001),* Employee(nameAce, age22, salary2000.0, mobile5924001),* Employee(nameKeith, age35, salary4000.0, mobile3924401)]*/
class Employee {String name;int age;double salary;long mobile;// constructors, getters setterspublic Employee(String name, int age, double salary, long mobile) {this.name name;this.age age;this.salary salary;this.mobile mobile;}public String getName() {return name;}public void setName(String name) {this.name name;}public int getAge() {return age;}public void setAge(int age) {this.age age;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary salary;}public long getMobile() {return mobile;}public void setMobile(long mobile) {this.mobile mobile;}Overridepublic String toString() {final StringBuilder sb new StringBuilder(Employee{);sb.append(name).append(name).append(\);sb.append(, age).append(age);sb.append(, salary).append(salary);sb.append(, mobile).append(mobile);sb.append(});return sb.toString();}
}使用 Comparator.comparing 进行排序
comparing 方法一
查看 Comparator 类内部实现还有一个 comparing 方法实现如下 public static T, U extends Comparable? super U ComparatorT comparing(Function? super T, ? extends U keyExtractor){Objects.requireNonNull(keyExtractor);return (ComparatorT Serializable)(c1, c2) - keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));}其返回值是 (c1, c2) - keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2)); 一个lambda表达式也就是一个Compator 。所以上面那个例子也可以改造成 如下
package com.common;import java.util.*;public class ComparatorTest {public static void main(String[] args) {Employee e1 new Employee(John, 25, 3000, 9922001);Employee e2 new Employee(Ace, 22, 2000, 5924001);Employee e3 new Employee(Keith, 35, 4000, 3924401);ListEmployee employees new ArrayList();employees.add(e1);employees.add(e2);employees.add(e3);/*** SuppressWarnings({unchecked, rawtypes})* default void sort(Comparator? super E c) {* Object[] a this.toArray();* Arrays.sort(a, (Comparator) c);* ListIteratorE i this.listIterator();* for (Object e : a) {* i.next();* i.set((E) e);* }* }** sort 对象接收一个 Comparator 函数式接口可以传入一个lambda表达式*/employees.sort((o1, o2) - o1.getName().compareTo(o2.getName()));Collections.sort(employees, (o1, o2) - o1.getName().compareTo(o2.getName()));employees.forEach(System.out::println);/*** Comparator.comparing 方法的使用** comparing 方法接收一个 Function 函数式接口 通过一个 lambda 表达式传入**/employees.sort(Comparator.comparing(e - e.getName()));/*** 该方法引用 Employee::getName 可以代替 lambda表达式*/employees.sort(Comparator.comparing(Employee::getName));}
}/*** [Employee(nameJohn, age25, salary3000.0, mobile9922001),* Employee(nameAce, age22, salary2000.0, mobile5924001),* Employee(nameKeith, age35, salary4000.0, mobile3924401)]*/
class Employee {String name;int age;double salary;long mobile;// constructors, getters setterspublic Employee(String name, int age, double salary, long mobile) {this.name name;this.age age;this.salary salary;this.mobile mobile;}public String getName() {return name;}public void setName(String name) {this.name name;}public int getAge() {return age;}public void setAge(int age) {this.age age;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary salary;}public long getMobile() {return mobile;}public void setMobile(long mobile) {this.mobile mobile;}Overridepublic String toString() {final StringBuilder sb new StringBuilder(Employee{);sb.append(name).append(name).append(\);sb.append(, age).append(age);sb.append(, salary).append(salary);sb.append(, mobile).append(mobile);sb.append(});return sb.toString();}
}comparing 方法二 public static T, U ComparatorT comparing(Function? super T, ? extends U keyExtractor,Comparator? super U keyComparator){Objects.requireNonNull(keyExtractor);Objects.requireNonNull(keyComparator);return (ComparatorT Serializable)(c1, c2) - keyComparator.compare(keyExtractor.apply(c1),keyExtractor.apply(c2));}和comparing 方法一不同的是 该方法多了一个参数 keyComparator keyComparator 是创建一个自定义的比较器。
Collections.sort(employees, Comparator.comparing(Employee::getName, (s1, s2) - {return s2.compareTo(s1);}));使用 Comparator.reversed 进行排序
返回相反的排序规则
/*** 相反的排序规则*/
Collections.sort(employees, Comparator.comparing(Employee::getName).reversed());employees.forEach(System.out::println);输出
Employee{nameKeith, age35, salary4000.0, mobile3924401}
Employee{nameJohn, age25, salary3000.0, mobile9922001}
Employee{nameAce, age22, salary2000.0, mobile5924001}使用 Comparator.nullsFirst进行排序
当集合中存在null元素时可以使用针对null友好的比较器null元素排在集合的最前面
employees.add(null); //插入一个null元素
Collections.sort(employees, Comparator.nullsFirst(Comparator.comparing(Employee::getName)));
employees.forEach(System.out::println);Collections.sort(employees, Comparator.nullsLast(Comparator.comparing(Employee::getName)));
employees.forEach(System.out::println);使用 Comparator.thenComparing 排序
首先使用 name 排序紧接着在使用ege 排序来看下使用效果
Collections.sort(employees, Comparator.comparing(Employee::getAge).thenComparing(Employee::getName));
employees.forEach(System.out::println);