是否存在可按指定Comparator实现排序并分组的Java数据结构?
有没有Java数据结构能通过指定Comparator完成排序+分组?
我需要实现的效果是:按自定义Comparator判定的“相等”规则对元素分组,同时各组遵循Comparator的排序规则排列,并且保留每个元素的完整实例(不是仅统计出现次数)。
示例1:基础类型场景
输入:
[1, 2, 1, 3, 4, 4, 5, 3]
期望输出:
[[1,1], [2], [3,3], [4,4], [5]] // 已按规则排序,所有"相等"元素的实例都被保留
我试过TreeMultiset或TreeBag,但它们只存储单个元素和出现次数,无法保留每个元素的实例。
示例2:自定义对象场景
假设有一组Book对象列表:
List<Book> books = [ {author: "1", title: "Book1", ...}, {author: "1", title: "Book2", ...}, {author: "0", title: "Book0", ...} ... ];
希望存在这样的数据结构:
UnknownDataStructure<Book> booksByAuthor = new UnknownDataStructure<>(Comparator.comparing(Book::getAuthor)); booksByAuthor.addAll(books);
最终结构等价于按作者分组并排序后的列表:
[ [{author: "0", title: "Book0", ...}], [{author: "1", title: "Book1", ...}, {author: "1", title: "Book2", ...}], ... ];
核心需求细节
我的Comparator是可灵活配置的,能基于Book的任意字段组合,还支持为每个字段单独设置排序方向、nullsFirst/nullsLast规则,例如:
Comparator.comparing(Book::getAuthor) .thenComparing(Comparator.comparing(Book::getTitle).reversed()) .thenComparing(Book::getRating, Comparator.nullsLast(Integer::compare))
核心目标就是:用指定的Comparator完成列表排序,同时将所有被Comparator判定为相等(即compare(a,b)返回0)的元素归为同一组,且保留每个元素的完整实例。
已尝试的方案
我曾创建了一个SortKey记录类:
public record SortKey(List<Comparable> values) { }
为每个Book生成对应的SortKey,存入排序所需的所有字段值,再用TreeMap<SortKey, List<Book>>来实现分组和排序。但这种方式过于繁琐,SortKey仅作为Map的键存在,完全是冗余的中间对象。
想请教:有没有办法仅通过提供Comparator实例就能实现需求,无需额外创建SortKey这类中间对象?
内容的提问来源于stack exchange,提问作者Dmitry
相关产品推荐
相关产品推荐

