Java Group By Object属性并获取Maximum



我有Documents对象,我想按文档ID对其进行分组。对它们进行分组后,我想得到它们的"最大值";。这就是我目前所拥有的:

List<Document> docList = getDocuments(...);
Map<Long, Document> docIdsToLatestDocVersions = docList.stream()
.collect(Collectors.groupingBy(
Document::getDocumentId,
Collectors.reducing(BinaryOperator.maxBy(Comparator.comparing( Function.identity() ))
));

文档类别:

class Document {
int documentId;
int majorVersion;
int minorVersion;
@Override
public int compareTo(Document document) {
return new CompareToBuilder()
.append(this.getDocumentId(), document.getDocumentId())
.append(this.getMajorVersion(), document.getMajorVersion())
.append(this.getMinorVersion(), document.getMinorVersion())
.toComparison();
}
}

重要的是,我已经实现了compareTo函数。我不知道该在groupingBy子句的reducer自变量中放什么。我也试过:

Map<Long, Document> docIdsToLatestDocVersions = docList.stream()
.collect(Collectors.toMap(
Document::getDocumentId, Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(d -> d))));

但无济于事。

在您的第一个代码段中,Collectors.reducing将返回一个Optional,您需要将结果映射的类型更改为Map<Integer, Optional<Document>>,或者将reduction收集器包装到collectingAndThen收集器中以打开包装Optional:

Map<Integer, Document> docIdsToLatestDocVersions =
docList.stream()
.collect(Collectors.groupingBy(Document::getDocumentId,
Collectors.collectingAndThen(
Collectors.reducing(BinaryOperator.maxBy(Document::compareTo)),
Optional::get)));

但正如您已经提到并尝试过的,每当您在分组后遇到Optionals时,最好检查Collectors.toMap是否是更好的选择。在这种情况下,它确实更可读:

Map<Integer, Document> docIdsToLatestDocVersions_second =
docList.stream()
.collect(Collectors.toMap(Document::getDocumentId,
Function.identity(),
BinaryOperator.maxBy(Document::compareTo)));

相关内容

  • 没有找到相关文章

最新更新