【问题标题】:Java Stream group by one attribute and collect max element by another attributeJava Stream 按一个属性分组并按另一个属性收集最大元素
【发布时间】:2020-03-15 21:55:47
【问题描述】:

我想知道流(或收集器)中是否已经实现了一个功能,它首先按属性对流进行分组,然后返回列表中按另一个属性排序的第一个元素。例如。以下代码尝试使用第一个属性对对象流进行分组,然后想要收集具有第二个属性的最高值的对象。

class MyClass{
 String att1;
 String att2;
}

现在,我想用 Stream myClassStream 实现这样的目标 -

Map<String,MyClass> myMap = myClassStream().collect(Collectors.groupingBy(MyClass::getAtt1)); //Now I want to do Sorting after grouping to collect only the element which has the highest value of attr2.

我使用简单 for 循环的代码是:

Map<String, MyClass> postAnalyticsMap = new HashMap<>();
for (MyClass post : myClassList) {
      if (post.get(post.getAtt1()) == null) {
               post.put(post.getAtt1(), post);
      } else {
               MyClass existingClass = postAnalyticsMap.get(post.getAtt1());
               if (existingPostAnalytics.getAtt2() < post.getAtt2()) {
                    postAnalyticsMap.put(post.getAtt1(), post);
               }
        }
  }

任何帮助将不胜感激。

【问题讨论】:

  • '....使用第一个属性对对象流进行分组,然后想要收集具有第二个属性的最高值的对象。' 你能包括带有此语句预期输出的示例输入?

标签: java java-8 java-stream


【解决方案1】:

使用带有合并功能的toMap 查找第二个属性的最大元素

Map<String, MyClass> map = myClassList.stream()
        .collect(Collectors.toMap(MyClass::getAtt1, Function.identity(),
                BinaryOperator.maxBy(Comparator.comparing(MyClass::getAtt2))));

【讨论】:

    【解决方案2】:

    你可以这样做:

    myClassStream()
         .collect(Collectors.groupingBy(MyClass::getAtt1,
                Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparing(MyClass::getAtt2)),
                                myClass -> myClass.map(MyClass::getAtt2).orElse(""))));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-11
      • 1970-01-01
      • 1970-01-01
      • 2014-12-18
      相关资源
      最近更新 更多