Collections.sort对List排序的两种方法

原文 http://blog.youkuaiyun.com/wxx614817/article/details/50628197

一、Collections.sort的简单使用

说到List的排序,第一反应当然是使用Collections.sort,方便简单。下面实现一下~~
[html] view plain copy
private void sortStrings() {
List list = new ArrayList();
list.add(“ccc”);
list.add(“aaa”);
list.add(“bbb”);
//排序
Collections.sort(list);
//输出
Log.d(TAG, “———–对字符串排序———–”);
for(String item : list) {
Log.d(TAG, item.toString());
}
}

[html] view plain copy
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的排序,非常简单。

二、问题提出

但在我们的项目中列表List的元素类型经常是自定义的,下面自定义了一个实体类Person:
[html] view plain copy
public class Person {

private String name;  
private int age;  

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

}

然后,想对Person的列表List进行排序,首先想到的也是通过Collections.sort进行排序:
[html] view plain copy
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) of type Collections is not applicable for the arguments (List). The inferred type Person is not a valid substitute for the bounded

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

三、Comparable实现排序

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

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进行排序并输出:
[html] view plain copy
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);  
}  

}

检查输出结果是否正确:
[html] view plain copy
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不需要做任何变化,如下:
[html] view plain copy
public class Person {

public String name;  
public int age;  

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

}

我们的比较器MyComparator的实现,主要是覆盖compare方法,在这个方法内实现比较的规则,具体代码:
[html] view plain copy
public class MyComparator implements Comparator {

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进行排序:
[html] view plain copy
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);  
}  

}

查看排序后的输出结果是否正确:
[html] view plain copy
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方法。

<think>好的,用户想了解如何使用Java的Collections.sortList<String>进行排序。首先,我需要回忆一下相关知识。记得Collections.sort两种常用的方法:一种是使用自然顺序排序,另一种是通过自定义比较器来排序。 根据引用[3],如果一个类实现了Comparable接口,就可以直接用Collections.sort进行自然排序。String类已经实现了Comparable,所以对于List<String>,直接调用Collections.sort(list)应该就能按字典序升序排列。那用户的问题应该包含这个方法的基本使用示例。 然后是降序排列。引用[1]提到可以使用Collections.sort(list, Collections.reverseOrder())来实现降序。这里需要传入一个比较器,reverseOrder()会返回一个逆序的比较器。因此,在示例中应该展示这两种情况:升序和降序。 接下来要考虑代码的正确性。例如,示例中的List<String>是否正确初始化,排序后的输出是否符合预期。可能需要先创建一个包含无序字符串的列表,然后分别调用两种排序方法,并打印结果。 还要注意用户可能的疑问,比如是否区分大小写。因为String的默认排序是区分大小写的,大写字母会排在小写字母前面。如果用户需要不区分大小写的排序,可能需要自定义比较器,比如使用String.CASE_INSENSITIVE_ORDER。虽然用户的问题中没有提到这点,但作为相关知识可以补充在相关问题里。 另外,引用[2]提到两种方法的源码,可能涉及到比较器的使用。比如,第二个方法需要传入自定义的Comparator,这可能用于更复杂的排序需求,但用户的问题主要集中在List<String>,所以暂时不需要深入这部分,但可以作为扩展知识提及。 最后,根据用户提供的引用,特别是引用[1]中的例子,需要确保代码示例的正确格式,比如使用正确的泛型语法,避免尖括号被转义。在回答中使用代码块,并正确显示List<String>的类型声明。 总结步骤:首先介绍自然排序(升序),然后降序,提供代码示例,解释各部分的作用,并补充可能的注意事项,如大小写问题。最后生成相关问题,帮助用户进一步学习。</think>### 使用 `Collections.sort` 对 `List<String>` 排序的示例 #### 1. **默认升序排序** 直接调用 `Collections.sort(list)`,按字符串的**字典序**(自然顺序)升序排列: ```java List<String> list = new ArrayList<>(); list.add("apple"); list.add("Banana"); list.add("cherry"); list.add("1_apple"); // 升序排序(字典序) Collections.sort(list); System.out.println("升序结果:" + list); // 输出:[1_apple, Banana, apple, cherry] ``` - **说明**:排序规则为 Unicode 值比较,数字 < 大写字母 < 小写字母[^3]。 --- #### 2. **降序排序** 通过 `Collections.reverseOrder()` 指定降序比较器: ```java // 降序排序(字典序反向) Collections.sort(list, Collections.reverseOrder()); System.out.println("降序结果:" + list); // 输出:[cherry, apple, Banana, 1_apple] ``` --- #### 3. **自定义排序规则(如忽略大小写)** 若需忽略大小写排序,可使用 `String.CASE_INSENSITIVE_ORDER` 比较器: ```java // 不区分大小写的升序 Collections.sort(list, String.CASE_INSENSITIVE_ORDER); System.out.println("不区分大小写升序:" + list); // 输出:[1_apple, apple, Banana, cherry] ``` --- ### 关键注意事项 1. **原列表被修改**:`Collections.sort` 直接修改原列表,而非返回新列表[^1]。 2. **排序稳定性**:对 `List<String>` 的排序是稳定的(相等元素顺序不变)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值