一、前言
最近在做一个需求用到了集合的排序,但是这个项目就有点老,用的jdk1.6的,所以不能用Stream流,我就想着把这几种都总结一遍吧,回顾一下。 先说明一下,我们是先对id进行排序,然后再对age进行排序的。
二、方式
(1)Comparator
Person p1 = new Person(100,108,"赵晓东");
Person p2 = new Person(5,20,"赵晓北");
Person p3 = new Person(9,88,"赵晓南");
Person p4 = new Person(10,100,"赵晓西");
Person p5 = new Person(15,200,"赵晓天");
ArrayList<Person> personList = new ArrayList<Person>();
personList.add(p1);
personList.add(p2);
personList.add(p3);
personList.add(p4);
personList.add(p5);
Collections.sort(personList, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int c = 0;
c =o1.getId()-o2.getId();
if (c==0){
c = o1.getAge()-o2.getAge();
}
return c;
}
});
personList.stream().forEach(e-> System.out.println(e));
System.out.println("====================================================");
展示
```java
Person(id=5, age=20, name=赵晓北)
Person(id=9, age=88, name=赵晓南)
Person(id=10, age=100, name=赵晓西)
Person(id=15, age=200, name=赵晓天)
Person(id=100, age=108, name=赵晓东)
====================================================
(2)Comparable
@Data
@AllArgsConstructor
public class Person implements Comparable<Person>{
private Integer id;
private Integer age;
private String name;
@Override
public int compareTo(Person o) {
int c = 0;
c=this.id-o.id;
if (c==0){
c=this.age-o.age;
}
return c;
}
}
展示
Person(id=5, age=20, name=赵晓北)
Person(id=9, age=88, name=赵晓南)
Person(id=10, age=100, name=赵晓西)
Person(id=15, age=200, name=赵晓天)
Person(id=100, age=108, name=赵晓东)
(3)Stream
List<Person> personList1 = personList.stream().sorted(Comparator.comparing(Person::getId).thenComparing(Person::getAge)).collect(Collectors.toList());
personList1.stream().forEach(e-> System.out.println(e));
Person(id=5, age=20, name=赵晓北)
Person(id=9, age=88, name=赵晓南)
Person(id=10, age=100, name=赵晓西)
Person(id=15, age=200, name=赵晓天)
Person(id=100, age=108, name=赵晓东)
三、性能对比
Comparator
执行时长: 0 毫秒.
Comparable
执行时长: 0 毫秒.
Stream
StopWatch stopWatch = new StopWatch();
stopWatch.start();
List<Person> personList1 = personList.stream().sorted(Comparator.comparing(Person::getId).thenComparing(Person::getAge)).collect(Collectors.toList());
stopWatch.stop();
System.out.printf("执行时长: %d 毫秒.%n",stopWatch.getTotalTimeMillis());
执行时长: 61 毫秒.
四、原理
comparable
是一个内比较器,实现了这一个排序接口,可以重写comPareTo方法,compareTo方法的返回值是int,有三种情况: 1、比较者大于被比较者,那么返回正整数 2、比较者等于被比较者,那么返回0 3、比较者小于被比较着,那么返回负整数 同时是可以支持和自己比较的。
Comparator
可以认为是一个外比较器。我们若需要控制某个类的次序,可以简历一个"该类的比较器"来进行排序。 所以如果当我们遇到不想按照原先的类进行排序的时候,可以写一个外部的comparator。
Stream
stream和Collection操作不同,有两个基本的特征 Pipelining: 中间操作队徽返回流对象本身。这样多个操作可以串联成一个管道。 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。Stream提供了内部迭代的方式, 通过访问者模式 (Visitor)实现。
五、总结
从用法方面看,Stream更好,但是有的时候项目不是Jdk1.8的就不得不用其它方式了, comparable是在java.lang包下面的。comparator是在java.util包下面的, comparable需要实现compareTo方法,comparator需要实现compare方法。 comparable通常需要在类里面写,而comparator不需要设置实体类里面。 从性能上面看,coomparable、comprartor、Stream性能相差不大,但是Stream会更加便利。
|