开发者

Java 中的排序Comparable 与 Comparator 的使用与区别对比解析

目录
  • 1. 背景
  • 2.Comparable接口
    • 2.1 定义
    • 2.2 返回值含义
    • 2.3 使用场景
  • 3.Comparator接口
    • 3.1 定义
    • 3.2 返回值含义
    • 3.3 使用场景
  • 4.ComparablevsComparator区别表
    • 5. Comparable 与 Comparator的使用示例:对List<Student>按age排序
      • 5.1 使用Comparable
      • 5.2 使用Comparator
        • 方式js一:匿名内部类
        • 方式二:Lambda 表达式(Java 8+推荐)
        • 方式三:方法引用(更简洁)
    • 6. 多条件排序(进阶)
      • 6.1使用Comparator实现多条件排序
        • 6.2 那是不是不能使用Comparable完成多条件呢?
          • 1️⃣Comparable的特点
          • 2️⃣Comparator的特点
          • 3️⃣ 多条件的对比
      • 7. 总结

        1. 背景

        在 Java 中,如果我们希望自定义类能够进行排序(例如在集合、数组中排序),就需要定义对象的比较规则。

        Java 提供了两种方式:

        • Comparable<T> 接口 → 在类内部实现,定义对象的“自然顺序”。
        • Comparator<T> 接口 → 在类外部定义比较器,可以灵活指定不同的排序规则。

        2.Comparable接口

        Java 中很多常用类都实现了 Comparable 接口,例如 StringInteger

        public class CompareToDemo {
            public static void main(String[] args) {
                // String 按字典序比较
                System.out.println("apple".compareTo("banana")); // -1
                System.out.println("dog".compareTo("dog"));      // 0
                System.out.println("zoo".compareTo("apple"));    // 正数
                // Integer 按数值大小比较
                Integer a = 10, b = 20;
                System.out.println(a.compareTo(b)); // -1
                System.out.println(b.compareTo(a)); // 1
                System.out.println(a.compareTo(10));// 0
            }
        }

        2.1 定义

        public interface Comparable<T> {
            int compareTo(T o);
        }
        

        2.2 php返回值含义

        • 负数:当前对象 < 参数对象
        • 0:当前对象 == 参数对象
        • 正数:当前对象 > 参数对象

        2.3 使用场景

        当一个类本身就有固定的“自然排序规则”,可以直接实现 Comparable

        3.Comparator接口

        3.1 定义

        public interface Comparator<T> {
            int compare(T o1, T o2);
        }

        3.2 返回值含义

        Comparable 相同:

        • 负数 → o1 < o2
        • 0 → o1 == o2
        • 正数 → o1 > o2

        3.3 使用场景

        当我们不想修改类本身,或者需要定义多种排序规则时,使用 Comparator 更灵活。

        4.ComparablevsComparator区别表

        特性ComparableComparator
        方法int compareTo(T o)int compare(T o1, T o2)
        定义位置内部(实现接口)外部(单独写比较器)
        排序规则数量一种(自然顺序)多种(可定义多个 Comparator)
        修改类代码需求需要修改类本身不需要修改类本身
        常见使用场景Collections.sort(list)Collections.sort(list, comparator)

        5. Comparable 与 Comparator的使用示例:对List<Student>按age排序

        5.1 使用Comparable

        class Student implements Comparable<Student> {
            private String name;
            private int age;
            public Student(String name, int age) {
                this.name = name;
                this.age = age;
            }
            // 定义“自然顺序”:按年龄升序
            @Override
            public int compareTo(Student other) {
                return Integer.compare(this.age, other.age);
            }
            @Override
            public String toString() {
                return name + "(" + age + ")";
            }
        }
        public class ComparableDemo {
            public static void main(String[] args) {
                List<Student> list = new ArrayList<>();
                list.add(new Student("Alice", 22));
                list.add(new Student("Bob", 18));
          GquoWhnZgO      list.add(new Student("Charlie", 20));
                // 使用 Comparable 定义的 compareTo 方法排序
                Collections.sort(list);
                System.out.println(list); 
                // 输出: [Bob(18), Charlie(20), Alice(22)]
            }
        }

        5.2 使用Comparator

        如果我们不想修改 Student 类,或者想要不同的排序规则,可以使用 Comparator

        方式一:匿名内部类

        Collections.sort(list, new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                return Integer.compare(s1.getAge(), s2.getAge());
            }
        });
        

        方式二:Lambda 表达式(Java 8+推荐)

        list.sort((s1, s2) -> Integer.compare(s1.getAge(), s2.getAge()));
        

        方式三:方法引用(更简洁)

        list.sort(Comparator.comparing(Student::getAge));
        

        输出结果同样是:

        [Bob(18), Charlie(20), Alice(22)]
        

        6. 多条件排序(进阶)

        6.1使用Comparator实现多条件排序

        使Comparator 时,可以轻松实现多条件排序。

        例如:先按年龄升序,再按名字字母序升序

        //方式一、方法引用 + 链式 Comparator
        list.sort(
            Comparator.comparing(Student::getAge)
                      .thenComparing(Student::getName)
        );
        //方式二、匿名内部类写法
        list.sort(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                // 先按年龄排序
                int result = Integer.compare(s1.getAge(), s2.getAge());
                // 如果年龄相同,则按姓名排序
                if (result == 0) {
                    result = s1.getName().compareTo(s2.getName());
                }
                return result;
            }
        });
        //方式三、Lambda 表达式写法(Java 8+ 推荐)
        list.sort((s1, s2) -> {
            int result = Integer.compare(s1.getAge(), s2.getAge());
            if (result == 0) {
                result = s1.getName().compareTo(s2.getName());
            }
            return result;
        });

        6.2 那是不是不能使用Comparable完成多条件呢?

        1️⃣Comparable的特点

        • Comparable自然排序(对象自己规定的排序规则)。
        • 一个类 只能实现一次 compareTo 方法,也就是说只能有一种排序逻辑。
        • 例子:
        public class Student implements Comparable<Student> {
            private int age;
            private String name;
            @Override
            public int compareTo(Student other) {
                // 先按年龄,再按姓名
                int result = Integer.compare(this.age, other.age);
                if (result == 0) {
                    result = this.name.compareTo(other.name);
                }
                return result;
            }
        }

        这样就能实现 多条件排序,但限制是 Student 这个类就被固定死了,始终用这一套排序规则(先按年龄升序,再按名字字母序升序),如果后续想先按照名字字母就要改这个compareTo方法

        2️⃣Comparator的特点

        • Comparator外部比较器,不修改实体类本身。
        • 可以定义多个不同的排序规则,根据需要随时切换。
        • 例子(用的上面使用Comparator 实现多条件排序的方式一):
        Comparator<Student> byAgeThenName = 
            Comparator.comparing(Student::getAge)
                      .thenComparing(Student::getName);
        Comparator<Student> byNameThenAge = 
            Comparator.comparing(Student::getName)
                      .thenComparing(Student::getAge);

        这样一个类(Student)就可以有 多种排序方式,灵活性更高。

        3️⃣ 多条件的对比

        • Comparable:类内部定义,固定一种排序逻辑(可以写多条件,但只能有这一种)。
        • Comparator:类外部定义,可以有多种排序逻辑,灵活组合,推荐用于多条件排序。

        这样就能实现 多条件排序,但限制是 Student 这个类就被固定死了,始终用这一套排序规则

        ✅ 多条件排序,Comparable 也能实现(在 compareTo 里写多条件逻辑)。

        ❌ 但是 Comparable 只能有这一种排序方式,灵活性差。

        真正业务里,一般 多条件排序都会用 Comparator

        7. 总结

        • Comparable:让类具备自然排序能力,适合“唯一固定规则”的场景。
        • Comparator:外部比较器,适合需要定义多种排序规则的场景。
          • 对于 List<Student>
          • 如果 Student 类实现了 Comparable,直接用 Collections.sort(list)
          • 如果不想改 Student 类,可以用 Comparator 方式排序。
        • 推荐使用 Comparator.编程客栈comparing(...) + Lambda/方法引用,更android简洁灵活。

        到此这篇关于java--Java 中的排序:Comparable 与 Comparator 的使用与区别的文章就介绍到这了,更多相关java Comparable 与 Comparator使用内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

        0

        上一篇:

        下一篇:

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        最新开发

        开发排行榜