当前位置: 首页 > news >正文

使用 Comparator 和 Comparable 对集合排序:如何轻松排序 Java 集合?

全文目录:

    • 开篇语
    • 前言
    • 1. `Comparable` 接口
      • 1.1. `Comparable` 接口的定义
      • 1.2. `Comparable` 排序示例
      • 输出:
    • 2. `Comparator` 接口
      • 2.1. `Comparator` 接口的定义
      • 2.2. `Comparator` 排序示例
      • 输出:
      • 2.3. `Comparator` 使用 lambda 表达式
      • 输出:
      • 2.4. 多种排序方式的组合
      • 输出:
    • 3. `Comparable` 和 `Comparator` 的比较
    • 4. 总结
    • 文末

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

在 Java 中,排序是我们常常会遇到的操作。幸运的是,Java 提供了两种非常常用的方式来对集合进行排序:ComparableComparator。它们分别适用于不同的排序需求,并且各有其特点和使用场景。今天,我们将深入分析这两种排序机制,并通过代码示例帮助你理解如何灵活地对集合进行排序。

1. Comparable 接口

Comparable 接口是 Java 自带的用于对对象进行排序的机制。它允许对象按照自然顺序进行排序,通常用于当你希望一个类的实例对象在没有外部干预的情况下就能比较大小的情况。

1.1. Comparable 接口的定义

Comparable 接口只有一个方法 compareTo(),它定义了当前对象与传入对象的比较规则。

public interface Comparable<T> {int compareTo(T o);
}
  • 返回值:
    • 负数:当前对象小于传入对象
    • :当前对象等于传入对象
    • 正数:当前对象大于传入对象

1.2. Comparable 排序示例

假设我们有一个 Person 类,其中包含 nameage 两个属性,我们希望按照 age 从小到大进行排序。我们可以实现 Comparable 接口,并重写 compareTo() 方法。

import java.util.*;class Person implements Comparable<Person> {String name;int age;public Person(String name, int age) {this.name = name;this.age = age;}// 实现 compareTo 方法,按 age 排序@Overridepublic int compareTo(Person other) {return Integer.compare(this.age, other.age);}@Overridepublic String toString() {return name + ": " + age;}
}public class ComparableExample {public static void main(String[] args) {List<Person> people = new ArrayList<>();people.add(new Person("Alice", 30));people.add(new Person("Bob", 25));people.add(new Person("Charlie", 35));// 使用 Collections.sort 对集合进行排序Collections.sort(people);// 打印排序后的结果for (Person person : people) {System.out.println(person);}}
}

输出:

Bob: 25
Alice: 30
Charlie: 35

在上面的代码中,Person 类实现了 Comparable 接口,重写了 compareTo() 方法,按照 age 进行排序。当我们调用 Collections.sort() 方法时,集合就会按照 compareTo() 方法的逻辑进行排序。

2. Comparator 接口

Comparator 接口是 Java 提供的另一种排序机制,与 Comparable 不同,它并不改变对象本身,而是提供一个外部的比较器来定义排序规则。使用 Comparator,你可以在不修改对象类的情况下灵活地实现多种排序方式。

2.1. Comparator 接口的定义

Comparator 接口有两个重要的方法:

public interface Comparator<T> {int compare(T o1, T o2);
}
  • 返回值:
    • 负数o1 小于 o2
    • o1 等于 o2
    • 正数o1 大于 o2

2.2. Comparator 排序示例

如果我们希望对 Person 类按 name 字母顺序进行排序,而不影响按 age 排序的逻辑,我们可以使用 Comparator

import java.util.*;class Person {String name;int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return name + ": " + age;}
}public class ComparatorExample {public static void main(String[] args) {List<Person> people = new ArrayList<>();people.add(new Person("Alice", 30));people.add(new Person("Bob", 25));people.add(new Person("Charlie", 35));// 使用 Comparator 按 name 排序people.sort(new Comparator<Person>() {@Overridepublic int compare(Person p1, Person p2) {return p1.name.compareTo(p2.name);}});// 打印排序后的结果for (Person person : people) {System.out.println(person);}}
}

输出:

Alice: 30
Bob: 25
Charlie: 35

在这个例子中,我们没有修改 Person 类,而是创建了一个匿名 Comparator 类,在 compare() 方法中定义了按 name 排序的逻辑。使用 people.sort() 方法对列表进行了排序。

2.3. Comparator 使用 lambda 表达式

从 Java 8 开始,我们可以使用更简洁的方式来实现 Comparator,即通过 lambda 表达式。这样可以让代码更加简洁,减少冗余。

import java.util.*;class Person {String name;int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return name + ": " + age;}
}public class ComparatorLambdaExample {public static void main(String[] args) {List<Person> people = new ArrayList<>();people.add(new Person("Alice", 30));people.add(new Person("Bob", 25));people.add(new Person("Charlie", 35));// 使用 lambda 表达式按 name 排序people.sort((p1, p2) -> p1.name.compareTo(p2.name));// 打印排序后的结果for (Person person : people) {System.out.println(person);}}
}

输出:

Alice: 30
Bob: 25
Charlie: 35

通过 lambda 表达式,我们可以轻松实现按 name 排序,并且代码更加简洁。

2.4. 多种排序方式的组合

如果我们希望根据多个属性进行排序(例如先按 age 排序,如果 age 相同,再按 name 排序),可以使用 ComparatorthenComparing() 方法来组合多个排序条件。

import java.util.*;class Person {String name;int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return name + ": " + age;}
}public class MultiComparatorExample {public static void main(String[] args) {List<Person> people = new ArrayList<>();people.add(new Person("Alice", 30));people.add(new Person("Bob", 25));people.add(new Person("Charlie", 30));people.add(new Person("Dave", 25));// 按 age 排序,如果 age 相同,再按 name 排序people.sort(Comparator.comparingInt(Person::getAge).thenComparing(Person::getName));// 打印排序后的结果for (Person person : people) {System.out.println(person);}}
}

输出:

Bob: 25
Dave: 25
Alice: 30
Charlie: 30

通过 Comparator.comparingInt()thenComparing() 方法,我们实现了先按 age 排序,再按 name 排序的功能。

3. ComparableComparator 的比较

特性ComparableComparator
排序方式自然排序(类内部实现)外部比较器定义(灵活自定义排序规则)
实现的接口方法compareTo()compare()
修改对象类需要修改对象类无需修改对象类
使用场景类本身有天然的排序顺序时需要多种排序规则或对象类无法修改时

4. 总结

  • Comparable:适用于类本身已经有了自然排序顺序的情况,且仅需要一种排序方式。通过实现 compareTo() 方法,我们可以定义类的默认排序规则。
  • Comparator:适用于需要多种排序方式的场景,或者当我们不能修改原始类时。通过 compare() 方法,可以定义任意排序逻辑,甚至可以组合多个比较器进行复合排序。

在实际开发中,我们可以根据具体需求灵活选择使用 Comparable 还是 Comparator,并通过 Java 8 引入的 lambda 表达式来简化代码。

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。


版权声明:本文由作者原创,转载请注明出处,谢谢支持!

相关文章:

  • Edge Remover v18.7 绿色版:轻松卸载 Edge 浏览器,彻底清理残留数据
  • Electron学习大纲
  • linux-进程信号的产生
  • 可编辑PPT | 企业数字底座:数据中台构建路径、方法和实践数据中台架构解决方案
  • 解锁遥感数据密码:DeepSeek、Python 与 OpenCV 的协同之力
  • Python教程(四)参数提取pymysql
  • LeetCode算法题:电话号码的字母组合
  • T2000云腾边缘计算盒子在数猪场景中的应用|YOLOv8+NodeRED
  • 软考 系统架构设计师系列知识点之杂项集萃(57)
  • VS2019 - 修正导出项目的工程模板的错误
  • UI自动化测试框架:PO 模式+数据驱动
  • 长度最小的子数组(leetcode)
  • 联想混合式AI的“动力总成”构建记
  • 【Redis 进阶】哨兵模式
  • KUKA机器人中断编程2—中断相关的指令
  • JDK 安装与配置
  • cursor Too many报错 显示锁机器码怎么办?也就是Cursor的
  • 配置集群(yarn)
  • 医药级食品树脂杜笙树脂医药溶液去除苦味溶液净化
  • 未来技术展望:光子量子计算集成与连续变量可视化
  • 珠峰窗口期5月开启 普通人登一次有多烧钱?
  • 《致1999年的自己》:千禧之年的你在哪里?
  • 阚吉林任重庆市民政局党组书记,原任市委组织部主持日常工作的副部长
  • 宇数科技王兴兴:第一桶金来自上海,欢迎上海的年轻人加入
  • 71岁导演詹姆斯・弗雷病逝,曾执导《纸牌屋》、麦当娜MV
  • 纽约大学朗格尼医学中心的转型带来哪些启示?