在编写程序时,不可避免的一个问题就是排序。在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;
}
@Override
public String toString() {
return "People{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}';
}
}
@Test
public 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;
}
@Override
public String toString() {
return "People{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}';
}
}
@Test
public 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.NullPointerException
Collections.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()实现逆序。