A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 xiekai_sjz 于 2018-3-21 14:39 编辑

在集合框架的应用中,往往都要进行排序,排序规则多种多样,或者只是简单的字符串大小排序,简单的数字大小排序,但有时根据需求排序规则会比较复杂。这时就需要Collection.sort()的使用技巧了。
对数字大小进行排序(Integer):
[Java] 纯文本查看 复制代码
public void testSortInteger(){

        List<Integer> list = new ArrayList<Integer>();
        //往list中插入10个100以内的随机整数
        Random random = new Random();
        Integer k;
        for(int i=0;i<10;i++){

            do{//防止重复
                k=random.nextInt(100);//自动装箱,且k在100之内
            }while(list.contains(k));
            list.add(k);
            System.out.println("成功添加整数:"+k);
        }
        System.out.println("-----------排序前------------");
        for(Integer integer:list){
            System.out.println("元素:"+integer);
        }
        Collections.sort(list);//从小到大排序
        System.out.println("-----------排序后------------");
        for(Integer integer:list){
            System.out.println("元素:"+integer);
        }
    }

运行结果:
成功添加整数:44
成功添加整数:28
成功添加整数:18
成功添加整数:56
成功添加整数:73
成功添加整数:84
成功添加整数:2
成功添加整数:54
成功添加整数:65
成功添加整数:53
———–排序前————
元素:44
元素:28
元素:18
元素:56
元素:73
元素:84
元素:2
元素:54
元素:65
元素:53
———–排序后————
元素:2
元素:18
元素:28
元素:44
元素:53
元素:54
元素:56
元素:65
元素:73
元素:84

结果分析:
从结果可以看到,对int的包装类Integer进行了从小到大的排序。

对字符串进行排序(String):

[Java] 纯文本查看 复制代码
public void testSortString(){

        List<String> list = new ArrayList<String>();
        list.add("microsoft");
        list.add("google");
        list.add("Google");
        list.add("h");
        list.add("z");
        System.out.println("-----------排序前------------");
        for(String string:list){
            System.out.println("元素:"+string);
        }
        Collections.sort(list);
        System.out.println("-----------排序后------------");
        for(String string:list){
            System.out.println("元素:"+string);
        }
//      排列顺序:
//      数字:0-9     48---57
//      大写字母:A-Z     65---90
//      小写字母:a-z     97---122
    }

运行结果:
———–排序前————
元素:microsoft
元素:google
元素:Google
元素:h
元素:z
———–排序后————
元素:Google
元素:google
元素:h
元素:microsoft
元素:z


结果分析:
对字符串的排序,是一个个字符逐一比较,从小到大,跟字符串长度基本没有关系。从运行结果就能看出字符串的排序规则。

对普通对象的排序(Student):

[Java] 纯文本查看 复制代码
public void testSortStudent(){

        List<Student> list = new ArrayList<Student>();

        Random random = new Random();
        list.add(new Student(random.nextInt(1000)+"","小芳"));
        list.add(new Student(random.nextInt(1000)+"","小明"));
        list.add(new Student(random.nextInt(1000)+"","小红"));
        list.add(new Student(10000+"","哈哈"));
        System.out.println("-----------排序前------------");
        for(Student student:list){
            System.out.println("学生姓名:"+student.name+",学生id:"+student.id);
        }
        Collections.sort(list);
        System.out.println("-----------排序后------------");
        for(Student student:list){
            System.out.println("学生姓名:"+student.name+",学生id:"+student.id);
        }

如果这么写,编译器会报错,报错信息如下:
The method sort(List T) in the type Collections is not applicable for the arguments (List Student),意思是sort()方法不适用于对泛型为Student的List进行排序。为什么会这样呢?在API文档中详细查看对Collection.sort()的描述:
Sorts the specified list according to the order induced by the specified comparator. All elements in the list must be mutually comparable using the specified comparator (that is, c.compare(e1, e2) must not throw a ClassCastException for any elements e1 and e2 in the list).
即sort()方法操作的对象必须实现comparable接口。而我们的Student并不是comparable接口的实现类,所以报错。那为什么上面对Integer与String的排序就没有报错,因为String与Integer都实现了Comparable接口。在各自的类定义中都重写了Comparable接口的compareTo()方法.

因此,实现了的comparable接口就是默认的比较规则。那我们要实现根据学生id大小(字符串)对学生进行排序,Student就要实现Comparable接口并重写compareTo()方法。

Student.java:

[Java] 纯文本查看 复制代码
package com.imooc.collection;

import java.util.HashSet;
import java.util.Set;

public class Student implements Comparable<Student> {

    public String id;
    public String name;

    public Set<Course> courses; 
    public Student(String id, String name) {
        super();
        this.id = id;
        this.name = name;
        this.courses = new HashSet<Course>();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    @Override
    public int compareTo(Student o) {
        // TODO Auto-generated method stub
        return this.id.compareTo(o.id);//规则:学生**id字符串**从小到大排序
        //==0就是两者相等
        //>0就是前者比后者大
        //<0就是前者比后者小
    }
}

这时编译正常并运行得到运行结果:
———–排序前————
学生姓名:小芳,学生id:734
学生姓名:小明,学生id:292
学生姓名:小红,学生id:549
学生姓名:哈哈,学生id:10000
———–排序后————
学生姓名:哈哈,学生id:10000
学生姓名:小明,学生id:292
学生姓名:小红,学生id:549
学生姓名:小芳,学生id:734


结果分析:
根据学生id(字符串)对学生进行了id从小到大排序。




1 个回复

正序浏览
我来占层楼啊   
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马