浅谈Java中Collections.sort对List排序的两种方法

 更新时间:2021年12月3日 12:59  点击:277 作者:wxx614817

一、Collections.sort的简单使用

说到List的排序,第一反应当然是使用Collections.sort,方便简单。下面实现一下~~

 private void sortStrings() {
  List<String> list = new ArrayList<String>();
  list.add("ccc");
  list.add("aaa");
  list.add("bbb");
  //排序
  Collections.sort(list);
  //输出
  Log.d(TAG, "-----------对字符串排序-----------");
  for(String item : list) {
   Log.d(TAG, item.toString());
  }
 }

=02-03 10:32:25.821: D/wxx(4732): -----------对字符串排序-----------
02-03 10:32:25.821: D/wxx(4732): aaa
02-03 10:32:25.821: D/wxx(4732): bbb
02-03 10:32:25.821: D/wxx(4732): ccc

可见,实现了对List<String>的排序,非常简单。

二、问题提出

但在我们的项目中列表List的元素类型经常是自定义的,下面自定义了一个实体类Person:

public class Person {
 
 private String name;
 private int age;
 
 public Person(String name, int age) {
  this.name = name;
  this.age = age;
 }
}

然后,想对Person的列表List<Person>进行排序,首先想到的也是通过Collections.sort进行排序:

 private void sortPerson() {
  Person p1 = new Person("ccc", 20);
  Person p2 = new Person("aaa", 18);
  Person p3 = new Person("bbb", 16);
  
  List<Person> list = new ArrayList<Person>();
  list.add(p1);
  list.add(p2);
  list.add(p3);
  
  //排序
  Collections.sort(list);
 }

发现,代码直接报错了:

Bound mismatch: The generic method sort(List<T>) of type Collections is not applicable for the arguments (List<Person>). The inferred type Person is not a valid substitute for the bounded
 parameter <T extends Comparable<? super T>>

从上面可知,Person不是一个有效的参数类型,而应该extends Comparable。为什么?
原来,要排序嘛当然要有排序的规则,比如按身高从高到低,按年龄从小到大,等等,也就是要有比较。而String这个对象已经帮我们实现了Comparable接口,所以String类型自己就是可以比较的。而我们的Person如果想要排序,也必须能够按某种规则进行比较,也就是要实现一个比较器。我们可以通过实现Comparable或Comparator接口实现比较器 。

三、Comparable实现排序

Comparable实现比较器,是定义在Person类的内部的,所以实体类Person需要implements Comparable<Person>,然后重写compareTo方法,在此方法里实现比较规则,规则就是先比较名字,如果名字不一样则返回比较结果,如果名字一样,再比较年龄,返回比较结果:

public class Person implements Comparable<Person> {
 
 public String name;
 public int age;
 
 public Person(String name, int age) {
  this.name = name;
  this.age = age;
 }
 
 public int compareTo(Person another) {
  int i = name.compareTo(another.name); //比较名字字符串
  if (i == 0) { //如果名字一样,则继续比较年龄
   return age - another.age;
  } else { //首先比较名字,名字不一样,则返回比较结果
   return i;
  }
 }
}

后面就是对List<Person>进行排序并输出:

 private void sortByComparable() {
  Person p1 = new Person("bbb", 20);
  Person p2 = new Person("aaa", 18);
  Person p3 = new Person("bbb", 16);
  
  List<Person> list = new ArrayList<Person>();
  list.add(p1);
  list.add(p2);
  list.add(p3);
  
  //排序
  Collections.sort(list);
  //输出
  Log.d(TAG, "-----------使用Comparable实现的排序-----------");
  for(Person item : list) {
   Log.d(TAG, "name = "+item.name+", age = "+item.age);
  }
 }

检查输出结果是否正确:

02-03 12:05:31.356: D/wxx(9936): -----------使用Comparable实现的排序-----------
02-03 12:05:31.356: D/wxx(9936): name = aaa, age = 18
02-03 12:05:31.356: D/wxx(9936): name = bbb, age = 16
02-03 12:05:31.356: D/wxx(9936): name = bbb, age = 20

四、Comparator实现排序

Comparator实现比较器,是定义在Person类的外部的,因此实体类Person不需要做任何变化,如下:

public class Person {
 
 public String name;
 public int age;
 
 public Person(String name, int age) {
  this.name = name;
  this.age = age;
 }
}


我们的比较器My Comparator的实现,主要是覆盖compare方法,在这个方法内实现比较的规则,具体代码:

 public class MyComparator implements Comparator<Person> {
 
  public int compare(Person one, Person two) {
   int i = one.name.compareTo(two.name); //比较名字字符串
   if (i == 0) { //如果名字一样,则继续比较年龄
    return one.age - two.age;
   } else { //首先比较名字,名字不一样,则返回比较结果
    return i;
   }
  }
  
 }

上面的排序规则是:先比较name值进行排序,如果name值一样 ,再比较age值排序。

最后,当然是用我们的比较器对List<Person>进行排序:

 private void sortByComparator() {
  Person p1 = new Person("bbb", 20);
  Person p2 = new Person("aaa", 18);
  Person p3 = new Person("bbb", 16);
  
  List<Person> list = new ArrayList<Person>();
  list.add(p1);
  list.add(p2);
  list.add(p3);
  
  //排序
  Collections.sort(list, new MyComparator());
  //输出
  Log.d(TAG, "-----------使用Comparator实现的排序-----------");
  for(Person item : list) {
   Log.d(TAG, "name = "+item.name+", age = "+item.age);
  }
 }

查看排序后的输出结果是否正确:

02-03 11:51:34.996: D/wxx(1355): -----------使用Comparator实现的排序-----------
02-03 11:51:34.996: D/wxx(1355): name = aaa, age = 18
02-03 11:51:35.001: D/wxx(1355): name = bbb, age = 16
02-03 11:51:35.001: D/wxx(1355): name = bbb, age = 20

五、Comparable 与Comparator区别

上面已经分别实现了Comparable 与Comparator对List进行排序,他们有相似的地方,也有不同的地方:

1)Comparable 与Comparator都是java的接口,用来对自定义的实体对象进行比较;

2)Comparable 是定义在实体类内部的,所以实体类对象本身就有比较大小的可能。但如果想换一种比较规则,如先按年龄后按名字排序,那么就必须修改实体类Person本身;

3)Comparator是在实体类外部实现比较器的,所以对List排序时必须同时传入数据和比较器,如Collections.sort(list, new MyComparator());如果想换一种比较规则,则仅需要修改比较器MyComparator,而实体类Person则不需要改变;所以建议使用这种方法;

4)Comparable实现代码相对简单,Comparator实现代码相对复杂一点,但还是建议使用Comparator方法。

到此这篇关于浅谈Java中Collections.sort对List排序的两种方法的文章就介绍到这了,更多相关Java中Collections.sort List排序 内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

原文出处:https://blog.csdn.net/wxx614817/article/details/50628197

[!--infotagslink--]

相关文章

  • Java实现经典游戏复杂迷宫

    这篇文章主要介绍了如何利用java语言实现经典《复杂迷宫》游戏,文中采用了swing技术进行了界面化处理,感兴趣的小伙伴可以动手试一试...2022-02-01
  • Java8 实现stream将对象集合list中抽取属性集合转化为map或list

    这篇文章主要介绍了Java8 实现stream将对象集合list中抽取属性集合转化为map或list的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-05
  • java8如何用Stream查List对象某属性是否有重复

    这篇文章主要介绍了java8如何用Stream查List对象某属性是否有重复的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-11
  • java 运行报错has been compiled by a more recent version of the Java Runtime

    java 运行报错has been compiled by a more recent version of the Java Runtime (class file version 54.0)...2021-04-01
  • 在java中获取List集合中最大的日期时间操作

    这篇文章主要介绍了在java中获取List集合中最大的日期时间操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
  • C#中list用法实例

    这篇文章主要介绍了C#中list用法,结合实例形式分析了C#中list排序、运算、转换等常见操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • 教你怎么用Java获取国家法定节假日

    这篇文章主要介绍了教你怎么用Java获取国家法定节假日,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下...2021-04-23
  • Java如何发起http请求的实现(GET/POST)

    这篇文章主要介绍了Java如何发起http请求的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-31
  • antdesign-vue结合sortablejs实现两个table相互拖拽排序功能

    这篇文章主要介绍了antdesign-vue结合sortablejs实现两个table相互拖拽排序功能,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-09
  • 浅谈Java与C#的一些细微差别

    说起C#和Java这两门语言(语法,数据类型 等),个人以为,大概有90%以上的相似,甚至可以认为几乎一样。但是在工作中,我也发现了一些细微的差别...2020-06-25
  • Java8处理List的双层循环问题

    这篇文章主要介绍了Java8处理List的双层循环问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-19
  • 解决Java处理HTTP请求超时的问题

    这篇文章主要介绍了解决Java处理HTTP请求超时的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-29
  • C# List 排序各种用法与比较

    这篇文章主要介绍了C# List 排序各种用法与比较的相关资料,需要的朋友可以参考下...2020-06-25
  • 使用list stream: 任意对象List拼接字符串

    这篇文章主要介绍了使用list stream:任意对象List拼接字符串操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-09
  • java 判断两个时间段是否重叠的案例

    这篇文章主要介绍了java 判断两个时间段是否重叠的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
  • 超简洁java实现双色球若干注随机号码生成(实例代码)

    这篇文章主要介绍了超简洁java实现双色球若干注随机号码生成(实例代码),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-04-02
  • C# 参数按照ASCII码从小到大排序(字典序)

    这篇文章主要介绍了C# 参数按照ASCII码从小到大排序(字典序)的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • Java生成随机姓名、性别和年龄的实现示例

    这篇文章主要介绍了Java生成随机姓名、性别和年龄的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-01
  • java 画pdf用itext调整表格宽度、自定义各个列宽的方法

    这篇文章主要介绍了java 画pdf用itext调整表格宽度、自定义各个列宽的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-31
  • js实现列表按字母排序

    这篇文章主要为大家详细介绍了js实现列表按字母排序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-11