List排序
1.JDK8前版本
List接口提供了sort函数定义,传入Comparator对象实例即可自定义排序。
default void sort(Comparator<? super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
常用的排序方式有两种:
两种方式的底层均为调用list default方法sort(Comparator<? super E> c)
List<Integer> list = Arrays.asList(3, 2, 1);
list.sort(null); // 调用listdefault方法
Collections.sort(list); // 调用Collections包装器sort()方法。
Collections.sort()和Collections.sort(comparator)内部实现:
省略参数时要求List内存放对象已实现Comparable接口!
形参类型为Comparator<? super E> c,传入未实现Comparable接口对象是会抛出java.lang.ClassCastException异常
public static <T extends Comparable<? super T>> void sort(List<T> list) {
list.sort(null);
}
public static <T> void sort(List<T> list, Comparator<? super T> c) {
list.sort(c);
}
2.JDK8版本新增
通过转换Stream + Lambda表达式实现,Stream接口提供如下方法:
Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);
代码实现
1.List存放已实现Comparable接口对象,下面两个调用方式实现效果相同。
List<Integer> list = Arrays.asList(3, 2, 1);
System.out.println(list);
// list.sort(null);
Collections.sort(list);
System.out.println(list);
打印结果:
[3, 2, 1]
[1, 2, 3]
2.自定义对象,排序
以Interval 自定义类为例,根据Interval的start属性升序排列如下:
以下实现分别通过调用list default sort方法、Collections静态sort方法和Stream流+Lambda表达式实现。
class Interval {
int start;
int end;
Interval() { start = 0; end = 0; }
Interval(int s, int e) { start = s; end = e; }
}
// 调用list default方法
private void intervalSort () {
List<Interval> list = Arrays.asList(new Interval(1, 2), new Interval(0, 2), new Interval(2, 4));
System.out.println(list);
// 传入匿名Comparator类实例
list.sort(new Comparator<Interval>() {
@Override
public int compare(Interval o1, Interval o2) {
if (o1.start > o2.start) {
return 1;
} else if (o1.start < o2.start) {
return -1;
} else {
return 0;
}
}
});
System.out.println(list);
}
// 调用Collections静态方法
private void intervalCollectionsSort () {
List<Interval> list = Arrays.asList(new Interval(1, 2), new Interval(0, 2), new Interval(2, 4));
System.out.println(list);
// 传入操作List和匿名Comparator类实例
Collections.sort(list, new Comparator<Interval>() {
@Override
public int compare(Interval o1, Interval o2) {
if (o1.start > o2.start) {
return 1;
} else if (o1.start < o2.start) {
return -1;
} else {
return 0;
}
}
});
System.out.println(list);
}
// Stream + lambad 实现
private void intervalStream () {
List<Interval> list = Arrays.asList(new Interval(1, 2), new Interval(0, 2), new Interval(2, 4));
System.out.println(list);
Comparator<Interval> c = new Comparator<Interval>() {
@Override
public int compare(Interval o1, Interval o2) {
if (o1.start > o2.start) {
return 100;
} else if (o1.start < o2.start) {
return -10;
} else {
return 0;
}
}
};
list = list.stream().sorted(c).collect(Collectors.toList());
System.out.println(list);
}
打印结果:
[[start: 1, end: 2], [start: 0, end: 2], [start: 2, end: 4]]
[[start: 0, end: 2], [start: 1, end: 2], [start: 2, end: 4]]
3.补充:关于实现Comparator接口
实现compare方法:
根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。一般用-1,0,和1表示。
int compare(T o1, T o2);
定义Comparator匿名实现类:
Comparator<Interval> c = new Comparator<Interval>() {
@Override
public int compare(Interval o1, Interval o2) {
if (o1.start > o2.start) {
return 100;
} else if (o1.start < o2.start) {
return -10;
} else {
return 0;
}
}
};