在编写程序时,不可避免的一个问题就是排序。在Java代码中如何对一个集合进行排序?我们今天就整理一个Java中用于排序的工具。
1.原子类型数组排序
对于原子类型数组排序,Arrays.sort。且只能由小到大的排序。无法使用Comparator
Arrays.sort(array);
2.引用类型数组排序
引用类型数组或者集合排序,就可以使用Comparator
Integer[] array = {3,2,6,1,7,2,78,11};Arrays.sort(array, (x,y)->y-x);//结果:[78, 11, 7, 6, 3, 2, 2, 1]System.out.println(Arrays.toString(array));
- Comparator需要重写一个,2个入参和返回1个整型的结果
整数的正、负代表2个数是否调换位置,y是x后面的数
- +: 说明需要调换,y,x
- -: 说明不需要调换 x,y
- 0: 也不用调换
3.引用类型集合排序
List<Integer> integers = Arrays.asList(3, 2, 6, 1, 7, 2, 78, 11);Collections.sort(integers);//[1, 2, 2, 3, 6, 7, 11, 78]System.out.println(integers);Collections.sort(integers,(x,y)->y-x);//[78, 11, 7, 6, 3, 2, 2, 1]System.out.println(integers);
4.Comparator的用法
前面的一些演示,主要目的是说,Comparator一般放在哪些地方。下面具体演示一些用法
手写lamda表达式法
List<Integer> integers = Arrays.asList(3, 2, 6, 1, 7, 2, 78, 11);Collections.sort(integers,(x,y)->y-x);//[78, 11, 7, 6, 3, 2, 2, 1]System.out.println(integers);
提取可比较字段类型比较
class People {private Integer id;private String name;private Integer age;public People(Integer id, String name, Integer age) {this.id = id;this.name = name;this.age = age;}public Integer getAge() {return age;}@Overridepublic String toString() {return "People{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}';}}@Testpublic void testComparing() {List<People> people = Arrays.asList(new People(1, "高溪", 23),new People(2, "James", 37),new People(3, "Kobe", 32),new People(4, "WY", 25));Collections.sort(people,Comparator.comparing(People::getAge));System.out.println(people);}
- 按照
People类的age字段进行排序 - Comparator.comaring(),提供一个排序的字段
int、double等确定排序字段类型
class People {private Integer id;private String name;private Integer age;public People(Integer id, String name, Integer age) {this.id = id;this.name = name;this.age = age;}public Integer getAge() {return age;}public Integer getId() {return id;}public String getName() {return name;}@Overridepublic String toString() {return "People{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}';}}@Testpublic void testComparing() {List<People> people = Arrays.asList(new People(1, "高溪", 23),new People(3, "James", 37),new People(2, "Kobe", 37),new People(4, "WY", 25));Collections.sort(people,Comparator.comparingInt(People::getAge));System.out.println(people);}
- 排序字段age是Integer
- 直接可以指定按照int排序
按照多个字段排序
List<People> people = Arrays.asList(new People(1, "高溪", 23),new People(3, "James", 37),new People(2, "Kobe", 37),new People(4, "WY", 25));Collections.sort(people,Comparator.comparingInt(People::getAge).thenComparing(Comparator.comparingInt(People::getId)));System.out.println(people);
- age如果相同按照id排序
null字段处理
List<People> people = Arrays.asList(new People(1, "高溪", 23),new People(3, "James", 37),new People(2, "Kobe", null),new People(4, "WY", 25));//fixme: java.lang.NullPointerExceptionCollections.sort(people,Comparator.comparing(People::getAge));System.out.println(people);
如果字段有null值,会报错
List<People> people = Arrays.asList(new People(1, "高溪", 23),new People(3, "James", 37),new People(2, "Kobe", null),new People(4, "WY", 25));Collections.sort(people,Comparator.comparing(People::getAge,Comparator.nullsFirst(Comparator.naturalOrder())));System.out.println(people);
先指定排序字段
nullFisrt中指定的是对 所提取字段的排序方式。
List<People> people = Arrays.asList(new People(1, "高溪", 23),new People(3, "James", 37),new People(2, "Kobe", null),new People(4, "WY", 25));Collections.sort(people,Comparator.comparing(People::getAge,Comparator.nullsFirst(Comparator.comparingInt(x->-x))));System.out.println(people);
nullFirst中的比较器是提取字段的值再提取
自然排序和逆序排序
List<People> people = Arrays.asList(new People(1, "高溪", 23),new People(3, "James", 37),new People(2, "Kobe", 34),new People(4, "WY", 25));Collections.sort(people,Comparator.comparing(People::getAge,Comparator.reverseOrder()));System.out.println(people);Collections.sort(people,Comparator.comparing(People::getAge,Comparator.naturalOrder()));System.out.println(people);
- 提取字段一定是可排序字段, 实现了
Comparable - 默认是自然排序
- 可以通过调用Comparator.reverseOrder()实现逆序。
