Comparator 在 Java 集合框架中的应用
在 Java 集合框架中,许多方法的参数会用到 Comparator 比较器,用于自定义元素的排序规则。以下是常见的涉及 Comparator 的方法分类及补充说明:
一、List 接口及其实现类(如 ArrayList、LinkedList 等)
方法:
sort(Comparator<? super E> c)作用:对列表进行原地排序(修改原列表),排序规则由传入的 Comparator 定义;若传入null,则使用元素的自然排序(需实现Comparable)。示例:
// 自定义Transaction类(含value属性)
class Transaction {
private int value;
public Transaction(int value) { this.value = value; }
public int getValue() { return value; }
}
List<Transaction> list = new ArrayList<>();
list.add(new Transaction(30));
list.add(new Transaction(10));
list.add(new Transaction(20));
// 按value升序排序(方法引用+Comparator静态方法)
list.sort(Comparator.comparingInt(Transaction::getValue));
// 结果:[Transaction(value=10), Transaction(value=20), Transaction(value=30)]
// 按value降序排序(反向排序)
list.sort(Comparator.comparingInt(Transaction::getValue).reversed());
二、Collections 工具类(静态方法)
1. sort(List<T> list, Comparator<? super T> c)
作用:对列表进行排序,功能与
List.sort()完全一致,是 Java 8 之前的主流排序方式,Java 8 后推荐直接使用List.sort()。示例:
Collections.sort(list, (t1, t2) -> t2.getValue() - t1.getValue()); // 按value降序
2. max(Collection<T> coll, Comparator<? super T> comp)
作用:根据
Comparator规则,返回集合中的最大值元素(无自然排序依赖)。示例:
Transaction maxTrans = Collections.max(list, Comparator.comparingInt(Transaction::getValue));
System.out.println(maxTrans.getValue()); // 输出30(最大值)
3. min(Collection<T> coll, Comparator<? super T> comp)
作用:根据
Comparator规则,返回集合中的最小值元素。示例:
Transaction minTrans = Collections.min(list, Comparator.comparingInt(Transaction::getValue));
System.out.println(minTrans.getValue()); // 输出10(最小值)
4. binarySearch(List<T> list, T key, Comparator<? super T> c)
作用:在已按 Comparator 规则排序的列表中,通过二分查找定位元素
key的索引;若未找到,返回-(插入点) - 1(插入点为元素应插入的位置)。注意:列表必须先按相同的 Comparator 排序,否则结果不可靠。示例:
// 先排序(升序)
list.sort(Comparator.comparingInt(Transaction::getValue));
// 查找value=20的元素
int index = Collections.binarySearch(list, new Transaction(20), Comparator.comparingInt(Transaction::getValue));
System.out.println(index); // 输出1(对应第二个元素的索引)
三、Set 接口的有序实现类(如 TreeSet)
构造方法:
TreeSet(Comparator<? super E> comparator)作用:创建一个有序 Set(元素按 Comparator 规则排序,无重复元素);若传入null,则使用元素的自然排序(需实现Comparable)。特性:TreeSet 底层基于红黑树,添加 / 查询元素的时间复杂度为 O (logn)。示例:
Set<Transaction> treeSet = new TreeSet<>(Comparator.comparingInt(Transaction::getValue));
treeSet.add(new Transaction(20));
treeSet.add(new Transaction(10));
treeSet.add(new Transaction(30));
// 遍历结果:按value升序输出 [10, 20, 30]
四、Map 接口的有序实现类(如 TreeMap)
构造方法:
TreeMap(Comparator<? super K> comparator)作用:创建一个有序 Map(键按 Comparator 规则排序);若传入null,则按键的自然排序(需实现Comparable)。特性:TreeMap 底层基于红黑树,键不允许重复,支持范围查询(如subMap())。示例:
// 按键的字符串忽略大小写排序
Map<String, Integer> treeMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
treeMap.put("Apple", 1);
treeMap.put("banana", 2);
treeMap.put("Cherry", 3);
// 遍历键:[Apple, banana, Cherry](忽略大小写排序)
// 自定义键排序:按字符串长度排序
Map<String, Integer> lenMap = new TreeMap<>(Comparator.comparingInt(String::length));
lenMap.put("a", 1);
lenMap.put("abc", 3);
lenMap.put("ab", 2);
// 遍历键:[a, ab, abc](按长度升序)
五、Java 8+ 流(Stream)中的排序方法
方法:
Stream<T> sorted(Comparator<? super T> comparator)作用:对流中的元素按 Comparator 规则排序,返回新的流(不修改原集合);若传入null,则使用自然排序。示例:
List<Transaction> sortedList = list.stream()
.sorted(Comparator.comparingInt(Transaction::getValue).reversed()) // 降序
.collect(Collectors.toList()); // 收集为新列表
六、Comparator 的进阶用法
1. 组合比较(多字段排序)
使用
thenComparing()实现多条件排序,例如 “先按 value 升序,再按 id 升序”:
class Transaction {
private int value;
private int id;
// 构造器、getter省略
}
// 多字段排序:value升序 → id升序
Comparator<Transaction> cmp = Comparator.comparingInt(Transaction::getValue)
.thenComparingInt(Transaction::getId);
list.sort(cmp);
2. 处理 null 值
使用
nullsFirst()/nullsLast()指定 null 元素的排序位置(避免空指针):
// null元素排在最前,非null元素按value升序
list.sort(Comparator.nullsFirst(Comparator.comparingInt(Transaction::getValue)));
总结
1. Comparator 的核心场景
- 对列表(List)进行灵活排序(
sort方法);- 有序集合(TreeSet、TreeMap)中定义元素 / 键的排序逻辑;
- 查找集合的最大 / 最小值(
Collections.max/min);- 流处理中的排序操作(
Stream.sorted);- 二分查找的辅助规则(
Collections.binarySearch)。
2. 注意事项
- Comparator 是函数式接口,支持 Lambda 表达式、方法引用简化实现;
- 若元素已实现
Comparable(自然排序),仍可通过 Comparator 覆盖默认规则;- TreeSet/TreeMap 中,Comparator 规则需与
equals()一致(否则可能出现 “相等但不重复” 的元素)。
3. Comparable vs Comparator
| 特性 | Comparable(自然排序) | Comparator(自定义排序) |
|---|---|---|
| 排序逻辑位置 | 类内部实现(compareTo()) | 类外部实现(compare()) |
| 灵活性 | 单一排序规则 | 支持多规则、动态切换 |
| 适用场景 | 类的固定排序逻辑 | 临时 / 多条件排序需求 |
更多推荐

所有评论(0)