在 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())
灵活性单一排序规则支持多规则、动态切换
适用场景类的固定排序逻辑临时 / 多条件排序需求

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐