在学习和使用 Java 集合框架时,我们经常会遇到一些名字极为相似,但功能却大相径庭的类和接口。
Collection 和
Collections,
Comparable 和
Comparator,以及 Java 8 引入的
Collectors,分散开来学习的时候,经常会有种熟悉且模糊的感觉,现在我们横向梳理一下它们所有的关系
1. 核心概念辨析
Collection 与 Collections
这是最基础也是最容易混淆的一对
-
Collection(接口): 集合的“父接口”- 是什么?
java.util.Collection是一个接口。它是 Java 集合框架的根接口之一(另一个是Map),定义了所有单值集合(如List,Set,Queue)都必须具备的通用方法,比如add(),remove(),contains(),size(),iterator()等 - 一句话总结:
Collection是一个规范,它规定了“什么是集合”
// 你不能 new Collection(),但可以用它来引用具体的实现类 Collection<String> names = new ArrayList<>(); names.add("张三"); names.add("李四"); System.out.println("集合大小: " + names.size()); // 输出: 2 - 是什么?
-
Collections(工具类): 集合的“工具箱”- 是什么?
java.util.Collections是一个工具类(注意,名字末尾有个s)。它内部包含了大量静态方法,用于对Collection及其子类型的集合进行各种操作 - 作用: 排序 (
sort())、打乱顺序 (shuffle())、二分查找 (binarySearch())、创建线程安全的集合 (synchronizedList()) 等 - 一句话总结:
Collections是一个工具箱,它提供了“如何操作集合”的方法
List<Integer> numbers = new ArrayList<>(); numbers.add(3); numbers.add(1); numbers.add(2); // 使用工具箱里的排序工具 Collections.sort(numbers); System.out.println(numbers); // 输出: [1, 2, 3] - 是什么?
Comparable 与 Comparator
当我们需要对集合中的对象进行排序时,就要使用这对接口了
-
Comparable(接口): 对象的“自然排序”- 是什么?
java.lang.Comparable是一个接口。当一个类实现了这个接口,就意味着该类的对象拥有了“天生”的、默认的比较能力 - 如何实现? 在类的内部实现
compareTo(T o)方法 - 类比: 它就像物品自带的说明书,规定了它默认应该如何和其他同类物品比较。比如,
Integer类实现了Comparable,所以它天生就知道如何比较大小 - 一句话总结:
Comparable让对象“自己知道”如何比较大小
class Student implements Comparable<Student> { private String name; private int score; // ... 构造器和 getter ... @Override public int compareTo(Student other) { // 定义自然排序为按分数升序 return this.score - other.score; } } // Collections.sort(studentList); // 可以直接排序,因为 Student 自己知道怎么比Comparable 接口更常使用的形式是匿名内部类,即在 sort 中 new 一个 Comparable< Student >
- 是什么?
-
Comparator(接口): 对象的“自定义排序”- 是什么?
java.util.Comparator是一个接口。它作为一个外部的比较器,用于定义一个临时的、非默认的排序规则 - 如何实现? 创建一个实现了
compare(T o1, T o2)方法的类,或者更常用的是使用匿名内部类或 Lambda 表达式 - 类比: 它就像一个“第三方的裁判”,当物品没有自带比较规则,或者你想用一个新规则时,就由这个裁判来决定谁胜谁负
- 一句话总结:
Comparator定义了一个“第三方标准”来比较两个对象
List<Student> studentList = ...; // 规则1:按分数降序排 Comparator<Student> scoreDesc = (s1, s2) -> s2.getScore() - s1.getScore(); studentList.sort(scoreDesc); // Java 8 的 List.sort() // 规则2:按名字字母顺序排 Comparator<Student> nameAsc = Comparator.comparing(Student::getName); studentList.sort(nameAsc); - 是什么?
Collectors
-
Collectors(工具类): Stream 的“终点”- 是什么?
java.util.stream.Collectors是一个工具类,专门与 Java 8 的 Stream API 配合使用 - 作用: 它的核心作用是作为
stream.collect()方法的参数,将流中的元素进行“收集”和“汇总”,转换成我们需要的最终形式,如List、Set、Map,或者进行分组、计数、求平均值等聚合操作 - 一句话总结:
Collectors是 Stream 数据流的打包机器,决定了数据最后以什么形式输出
List<String> fruits = Arrays.asList("apple", "banana", "orange", "apple"); // 打包成 List List<String> fruitList = fruits.stream().collect(Collectors.toList()); // 打包成 Set (自动去重) Set<String> fruitSet = fruits.stream().collect(Collectors.toSet()); // 按首字母分组打包成 Map Map<Character, List<String>> groupedFruits = fruits.stream() .collect(Collectors.groupingBy(s -> s.charAt(0))); // 输出: {a=[apple, apple], b=[banana], o=[orange]} - 是什么?
2. 终极总结:一表对比它们的区别
Collection | Collections | Collectors | Comparable | Comparator | |
|---|---|---|---|---|---|
| 类型 | 接口 | 工具类 (所有方法静态) | 工具类 (所有方法静态) | 接口 | 接口 |
| 包 | java.util | java.util | java.util.stream | java.lang | java.util |
| 作用 | 定义单值集合的通用行为 | 对集合进行操作 (排序, 查找等) | Stream API 中用于收集/聚合数据 | 定义对象的**“自然排序”** | 定义对象的**“自定义/临时排序”** |
| 实例化 | 不能直接实例化,通过其实现类 | 不能实例化 (静态方法直接调用) | 不能实例化 (静态方法直接调用) | 由待排序的类实现 | 通常作为匿名类/Lambda 或单独的类实现 |
| 排序能力 | 无直接排序方法,依赖其实现类 | 包含静态排序方法 sort() | 间接通过 collect() 配合排序器(如 minBy) | 实现 compareTo() 方法 | 实现 compare() 方法 |
| 应用场景 | 声明 List<T>, Set<T> 等变量 | 对现有集合进行通用操作 | Stream 处理结果收集到集合或进行统计 | 对象具备**“天生”的排序规则**时 | 对象需要多种排序规则或无自然排序时 |
3. 补充与最佳实践
-
Comparable与Comparator的选择:- 如果一个对象的排序方式是主要的、固定的,比如学生的学号,那么应该让学生类实现
Comparable - 如果需要多种排序方式,比如按姓名排、按成绩排、按年龄排,那么应该为每种规则创建一个
Comparator。这样更灵活,也符合“开闭原则”
- 如果一个对象的排序方式是主要的、固定的,比如学生的学号,那么应该让学生类实现
-
List.sort()与Collections.sort():- 从 Java 8 开始,
List接口自身就有了sort(Comparator)方法 - 推荐使用
list.sort(comparator),因为它更直观,且性能可能略好(直接在List内部实现) Collections.sort()依然可用,特别是当需要兼容旧版本 Java 代码时
- 从 Java 8 开始,
-
记住它们的关系:
- 可以对一个
Collection(比如ArrayList)使用Collections工具类 - 在排序时,
Collections.sort()可以接受一个实现了Comparable的对象列表,或者接受一个列表和一个Comparator作为裁判 Collectors和前两者关系不大,它专属于 Stream API
- 可以对一个

439

被折叠的 条评论
为什么被折叠?



