当前位置: 首页 > 后端技术 > Java

Java中List的3种排序方式!

时间:2023-04-01 21:04:46 Java

在一些特殊场景下,我们需要在Java程序中对List集合进行排序。比如所有用户的列表是从第三方接口获取的,但是这个列表默认是按照用户数从小到大排序的,而我们的系统需要按照用户的年龄从大到小排序。这时候,我们需要对排序的List集合进行自定义的排序操作。List排序常用的三种方式:使用Comparable排序;使用Comparator进行排序;如果是JDK8以上的环境,也可以使用Stream进行排序。下面我们来看一下各种排序方式的具体实现。1.使用Comparable排序根据本文设计的场景,我们需要创建一个包含用户列表的List集合,将用户按照年龄从大到小排序。具体实现代码如下:publicclassListSortExample{publicstaticvoidmain(String[]args){//创建并初始化ListListlist=newArrayList(){{add(newPerson(1,30,"北京"));add(newPerson(2,20,"西安"));add(newPerson(3,40,"上海"));}};//使用Comparable自定义规则进行排序Collections.sort(list);//打印列表集合list.forEach(p->{System.out.println(p);});}}//下面的set/get/toString使用了lombok注解@Getter@Setter@ToStringclassPersonimplementsComparable{privateintid;私人年龄;私有字符串名称;publicPerson(intid,intage,Stringname){this.id=id;这个。年龄=年龄;this.name=名称;}@OverridepublicintcompareTo(Personp){returnp.getAge()-this.getAge();}}上面代码的执行结果如下图所示:该方法的核心代码如下:2、使用Comparator进行排序Comparable是类内部的比较方法,Comparator是sort类外部的比较器。使用Comparator比较器,不需要修改原来的Person类,只需要扩展Person类的一个比较器,Comparator的实现有两种方法:创建一个新的Comparator比较器;使用Comparator匿名类比较器。其中,第二种实现方式更为简洁。我们通过下面的具体代码来观察一下两者的区别。2.1创建一个新的ComparatorpublicclassListSortExample2{publicstaticvoidmain(String[]args){//创建并初始化ListListlist=newArrayList(){{add(newPerson(1,30,“北京”));add(newPerson(2,20,"西安"));add(newPerson(3,40,"上海"));}};//排序Collections.sort(list,newPersonComparator());//打印列表集合list.forEach(p->{System.out.println(p);});}}/***创建一个新的PersonComparator*/classPersonComparatorimplementsComparator{@Overridepublicintcompare(Personp1,Personp2){returnp2.getAge()-p1.getAge();}}@Getter@Setter@ToStringclassPerson{privateintid;私人年龄;私有字符串名称;publicPerson(intid,intage,Stringname){this.id=id;这个。年龄=年龄;this.name=名称;}}上面代码的执行结果如下图所示:该方法的核心实现代码如下:2.2匿名类比较器comparatorComparator可以使用更简洁的匿名类来实现排序功能。具体实现代码如下:publicclassListSortExample2{publicstaticvoidmain(String[]args){//创建并初始化ListListlist=newArrayList(){{add(newPerson(1,30,"北京"));add(newPerson(2,20,"西安"));add(newPerson(3,40,"上海"));}};//使用匿名比较器对集合进行排序。sort(list,newComparator(){@Overridepublicintcompare(Personp1,Personp2){returnp2.getAge()-p1.getAge();}});//打印列表集合list.forEach(p->{System.out.println(p);});}}@Getter@Setter@ToStringclassPerson{privateintid;私人年龄;私有字符串名称;publicPerson(intid,intage,Stringname){this.id=id;这个。年龄=年龄;this.name=名称;}}上面代码的执行结果如下图所示:3.使用Stream流排序在JDK8之后可以使用更简单的方法Stream流来实现目前的排序功能只需要一行代码,具体实现如下:publicclassListSortExample3{publicstaticvoidmain(String[]args){//创建并初始化ListListlist=newArrayList(){{add(newPerson(1,30,"北京"));add(newPerson(2,20,"西安"));add(newPerson(3,40,"上海"));}};//使用Stream排序list=list.stream().sorted(Comparator.comparing(Person::getAge).reversed()).collect(Collectors.toList());//打印列表集合list.forEach(p->{System.out.println(p);});}@Getter@Setter@ToStringstaticclassPerson{privateintid;私人年龄;私有字符串名称;publicPerson(intid,intage,Stringname){this.id=id;这个。年龄=年龄;this.name=名称;}}}其中reversed()表示倒序,如果不使用该方法则为正序上述代码的执行结果如下图所示:扩展:当排序字段为null,使用Stream进行排序时,如果排序字段为null值,则会出现异常。具体示例如下:publicclassListSortExample4{publicstaticvoidmain(String[]args){//创建并初始化ListListlist=newArrayList(){{add(newPerson(30,“北京”));add(newPerson(10,"西安"));add(newPerson(40,"上海"));add(newPerson(null,"上海"));//年龄为空值}};//按照[age]的正序排列,但是有一个空值list=list.stream().sorted(Comparator.comparing(Person::getAge)).collect(Collectors.toList());//打印列表集合list.forEach(p->{System.out.println(p);});}}@Getter@Setter@ToStringclassPerson{私有整数年龄;私有字符串名称;publicPerson(Integerage,Stringname){this.age=age;this.name=名称;}}上面代码的执行结果如下图所示:要解决上面的问题,需要给Comparator.comparing传递第二个参数:Comparator.nullsXXX,如下代码所示:publicclassListSortExample4{publicstaticvoidmain(String[]args){//创建并初始化列表Listlist=newArrayList(){{add(newPerson(30,"北京"));add(newPerson(10,"西安"));add(newPerson(40,"上海"));add(newPerson(null,"上海"));}};//按照[age]排序,但是age里面有空值list=list.stream().sorted(Comparator.comparing(Person::getAge,Comparator.nullsFirst(Integer::compareTo))).collect(收集器.toList());//打印列表集合list.forEach(p->{System.out.println(p);});}}@Getter@Setter@ToStringclassPerson{私有整数年龄;私有字符串名称;公共人(整数年龄,字符串名称){这个。年龄=年龄;this.name=名称;}}Comparator.nullsFirst表示将null值放在集合最前面的排序字段中。如果要将空值放在集合的末尾,可以使用Comparator.nullsLast上述代码的执行结果如下图所示:总结本文介绍三种List排序方式。前两种方式在JDK8之前的版本中比较常用,其中Comparator有两种实现方式,JDK8之后的版本可以使用Comparator.comparing来实现排序。如果排序字段可能出现空值,则使用Comparator.nullsXXX进行排序(否则会报错)。突然走近,不意外,没有理由,也没有愤怒。享受平凡生活的快乐,为生活而成长。博主:80后程序员。爱好:阅读、写作和慢跑。公众号:Java面试真题解析