Java Collections的sort排序详解

Java Collections框架中的sort方法是用于对List集合进行排序,它提供了两种主要的重载形式。

1、 基本sort方法

(1) 源码:

    public static <T extends Comparable<? super T>> void sort(List<T> list) {
        list.sort(null);
    }

(2) 特点

  • 要求集合元素必须实现Comparable接口
  • 使用元素的自然顺序进行排序(升序)
  • 时间复杂度为O(n log n),使用修改后的归并排序算法

(3) 代码:

List<String> names = Arrays.asList("John",  "Alice", "Bob", "Diana");
Collections.sort(names);  // 自然字典序排序 
// 结果: [Alice, Bob, Diana, John]

2、带Comparator的sort方法

(1) 源码:

   public static <T> void sort(List<T> list, Comparator<? super T> c) {
        list.sort(c);
    }

(2) 特点

  • 允许通过自定义Comparator实现灵活排序
  • 不要求元素实现Comparable接口
  • 适用于需要特殊排序逻辑的场景

  2.1 自定义排序规则

    代码:

        List<Integer> numbers = Arrays.asList(3,  1, 4, 1, 5, 9);
        Collections.sort(numbers,  (a, b) -> b - a); // 降序排序
        System.out.println(numbers); //[9, 5, 4, 3, 1, 1]

        Collections.sort(numbers,(a,b)->a-b); // 升序排序
        System.out.println(numbers);  //  [1, 1, 3, 4, 5, 9]

 2.2 多字段排序

    Student类:

public class Student {
    private String name;
    private int age;
    private Gender gender;

    public Gender getGender() {
        return gender;
    }

    //构造方法
    public Student() {
    }

    public Student(String name, int age, Gender gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public void setGender(Gender gender) {
        this.gender = gender;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender=" + gender +
                '}';
    }
}

// 枚举类型
enum Gender {
    MALE, FEMALE
}

   Test类:

        //泛型集合
        List<Student> list = new ArrayList<>();
        //学生对象
        Student stu1 = new Student("mike", 20,Gender.MALE);
        Student stu2 = new Student("john", 18, Gender.FEMALE);
        Student stu3 = new Student("boy", 21, Gender.MALE);
        Student stu4 = new Student("peter", 17, Gender.FEMALE);
        Student stu5 = new Student("azhangsan", 18, Gender.MALE);

        //添加到列表中
        list.add(stu1);
        list.add(stu2);
        list.add(stu3);
        list.add(stu4);
        list.add(stu5);

        System.out.println("\n***********排序前数据**********************");
        //foreach循环
        for (Student o : list) {
            System.out.println(o);
        }


        System.out.println("\n***********排序后数据:年龄升序排序************************");
        //lambda表达式排序,根据年龄排序
        Collections.sort(list, Comparator.comparing(Student::getAge));
        for (Student o : list) {
            System.out.println(o);
        }


        System.out.println("\n***********排序后数据:年龄降序排序************************");
        //lambda表达式排序,根据年龄排序
        Collections.sort(list, Comparator.comparing(Student::getAge, Comparator.reverseOrder()));
        for (Student o : list) {
            System.out.println(o);
        }


        System.out.println("\n***********排序后数据:年龄升序排序,如果年龄相同则按照名字排序******");
        //lambda表达式排序,根据年龄排序,如果年龄相同则按照名字排序
        Collections.sort(list, Comparator.comparing(Student::getAge).thenComparing(Student::getName));
        for (Student o : list) {
            System.out.println(o);
        }

 

     通过合理使用Collections.sort 方法,可以高效地处理各种排序需求,从简单的数字排序到复杂的多字段对象排序。

4、性能考虑

  • 对于小规模数据(元素数量<47),使用插入排序
  • 中等规模数据使用快速排序
  • 大规模数据使用归并排序
  • 对于已经部分排序的列表,性能会更好

5、注意事项

  1. 可变性:sort方法会直接修改原始列表,而不是返回新列表
  2. 稳定性:这是一个稳定排序,相等元素的相对顺序会保留
  3. null处理:自然排序不允许null元素,但Comparator可以自定义null处理
  4. 并发修改:如果在排序过程中列表被修改,会抛出ConcurrentModificationException
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值