当前位置: 首页 > 知识库问答 >
问题:

Java按对象属性分组并获取最大值

苏嘉歆
2023-03-14

我有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函数。我不确定在< code>groupingBy子句的< code>reducer参数中放什么。我也试过:

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

但无济于事。

共有1个答案

程志新
2023-03-14

在第一个代码段中,Collectors.reduce 将返回“可选”,您需要将结果地图的类型更改为“地图”

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

但是正如您已经提到并尝试过的,无论何时当您在分组后遇到选项时,最好检查一下< code>Collectors.toMap是否是更好的选择。在这种情况下,它确实更具可读性:

Map<Integer, Document> docIdsToLatestDocVersions_second =
     docList.stream()
            .collect(Collectors.toMap(Document::getDocumentId,
                                      Function.identity(),
                                      BinaryOperator.maxBy(Document::compareTo)));
 类似资料:
  • 我已经设法编写了一个使用Java8Streams API的解决方案,该解决方案首先按对象路由的值对其列表进行分组,然后对每组中的对象数进行计数。它返回映射路由->long。代码如下: 和路由类: 应转换为: 请注意,映射的键数为2条路由,它是lastUpdated值最大的一条。

  • 问题内容: 我设法使用Java 8 Streams API编写了一个解决方案,该解决方案首先按其值对对象Route列表进行分组,然后对每个组中的对象数进行计数。它返回一个映射Route-> Long。这是代码: 和Route类: 我还想实现的是,每个组的密钥都是lastUpdated值最大的密钥。我已经在研究此解决方案,但是我不知道如何组合计数和按值分组以及路由最大lastUpdated值。这是我

  • 问题内容: 我需要使用特定对象的属性(位置)对对象(学生)列表进行分组,代码如下所示, 请给我建议一个干净的方法。 问题答案: In Java 8:

  • 我想知道流(或收集器)中是否已经实现了一个功能,它首先按属性对流进行分组,然后返回列表中按另一个属性排序的第一个元素。例如,以下代码尝试使用第一个属性对对象流进行分组,然后希望收集第二个属性值最高的对象。 现在,我想用流myClassStream实现类似的功能- 我的代码使用简单的循环是: 任何帮助将不胜感激。

  • 问题内容: 如何转换为: 到这个: 使用javascript或下划线 问题答案: 假设原始列表包含在名为的变量中:

  • 我需要使用特定对象的属性(