本文介绍了Java中Collections.sort对List排序的两种方法以及Comparable 与Comparator区别,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
目录
一、Collections.sort的简单使用
二、问题提出
三、Comparable实现排序
四、Comparator实现排序
五、Comparable 与Comparator区别

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

  1. private void sortStrings() {
  2. List<String> list = new ArrayList<String>();
  3. list.add("ccc");
  4. list.add("aaa");
  5. list.add("bbb");
  6. //排序
  7. Collections.sort(list);
  8. //输出
  9. Log.d(TAG, "-----------对字符串排序-----------");
  10. for(String item : list) {
  11. Log.d(TAG, item.toString());
  12. }
  13. }

=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:

  1. public class Person {
  2. private String name;
  3. private int age;
  4. public Person(String name, int age) {
  5. this.name = name;
  6. this.age = age;
  7. }
  8. }

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

  1. private void sortPerson() {
  2. Person p1 = new Person("ccc", 20);
  3. Person p2 = new Person("aaa", 18);
  4. Person p3 = new Person("bbb", 16);
  5. List<Person> list = new ArrayList<Person>();
  6. list.add(p1);
  7. list.add(p2);
  8. list.add(p3);
  9. //排序
  10. Collections.sort(list);
  11. }

发现,代码直接报错了:

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方法,在此方法里实现比较规则,规则就是先比较名字,如果名字不一样则返回比较结果,如果名字一样,再比较年龄,返回比较结果:

  1. public class Person implements Comparable<Person> {
  2. public String name;
  3. public int age;
  4. public Person(String name, int age) {
  5. this.name = name;
  6. this.age = age;
  7. }
  8. public int compareTo(Person another) {
  9. int i = name.compareTo(another.name); //比较名字字符串
  10. if (i == 0) { //如果名字一样,则继续比较年龄
  11. return age - another.age;
  12. } else { //首先比较名字,名字不一样,则返回比较结果
  13. return i;
  14. }
  15. }
  16. }

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

  1. private void sortByComparable() {
  2. Person p1 = new Person("bbb", 20);
  3. Person p2 = new Person("aaa", 18);
  4. Person p3 = new Person("bbb", 16);
  5. List<Person> list = new ArrayList<Person>();
  6. list.add(p1);
  7. list.add(p2);
  8. list.add(p3);
  9. //排序
  10. Collections.sort(list);
  11. //输出
  12. Log.d(TAG, "-----------使用Comparable实现的排序-----------");
  13. for(Person item : list) {
  14. Log.d(TAG, "name = "+item.name+", age = "+item.age);
  15. }
  16. }

检查输出结果是否正确:

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不需要做任何变化,如下:

  1. public class Person {
  2. public String name;
  3. public int age;
  4. public Person(String name, int age) {
  5. this.name = name;
  6. this.age = age;
  7. }
  8. }

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

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

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

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

  1. private void sortByComparator() {
  2. Person p1 = new Person("bbb", 20);
  3. Person p2 = new Person("aaa", 18);
  4. Person p3 = new Person("bbb", 16);
  5. List<Person> list = new ArrayList<Person>();
  6. list.add(p1);
  7. list.add(p2);
  8. list.add(p3);
  9. //排序
  10. Collections.sort(list, new MyComparator());
  11. //输出
  12. Log.d(TAG, "-----------使用Comparator实现的排序-----------");
  13. for(Person item : list) {
  14. Log.d(TAG, "name = "+item.name+", age = "+item.age);
  15. }
  16. }

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

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方法。

更多相关文章

  1. python3中dict.keys().sort()用不了的解决方法
  2. js实现简单好玩的气泡
  3. 自定义方法,实现通过类名获取对象集合
  4. Java NIO实现群聊系统
  5. Java基于BIO实现文件上传功能
  6. Java实战在线选课系统的实现流程
  7. Java基于NIO实现聊天室功能
  8. 模拟数组pop,push,toString和冒泡排序(sort的使用)
  9. 用cookie实现简单的用户自定义页面样式

随机推荐

  1. Java中字符流和字节流到底有什么区别!!!
  2. 5个java面试题。。。请高手给个答案。。
  3. java中匹配字符串中的中文字符(含中文标
  4. Java nio 学习笔记(一) Buffer(缓冲区)与Chan
  5. 如何知道Object是否为String类型对象?
  6. Java实现图像对比类
  7. Eclipse Juno 4.2的Swing插件[重复]
  8. 关于JAVA类加载大家发表一下见解吧
  9. Java标准标签库学习小结
  10. Javascript实现页面加载完成后自动刷新一