有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何在forEach中执行操作并在Java流中将其传递给groupingBy

我想根据某个决定来划分我的名单。我也有一张地图来存储这些决定。 目前,我正在更新流本身中的决策。我觉得这不是一个好的做法,因为我用收集 计算分组标准以外的操作。我的另一个选择是再次穿过小溪 使用forEach更新地图,但这意味着我要使用getFinalDecision两次。有更好的方法吗?有办法吗 我可以在forEach中执行getFinalDecision并将其传递给groupingBy

val test = myList.stream().collect(groupingBy(t -> {
      A a = my_map.get(t.getSomething());
      A finalDecision = getFinalDecision(t.getSomeOtherThing(), a);
      my_map.put(t.getSomething(), finalDecision);
      return finalDecision;
}));

共 (2) 个答案

  1. # 1 楼答案

    您可以使用Map#compute简化代码:

    test = myList.stream().collect(groupingBy(t -> my_map.compute(t.getSomething()
                ,(it, a) -> getFinalDecision(t.getSomeOtherThing(), a))));
    

    使用Stream#peek&Stream#collect描述它有两件事:合并&&分组

    test = myList.stream()
        .map(it -> new SimpleEntry<>(it, getFinalDecision(it.getSomeOtherThing()
                                               , my_map.get(it.getSomething()))))
        .peek(it-> my_map.put(it.getKey(),it.getValue()))
        .collect(groupingBy(SimpleEntry::getValue
                           ,mapping(SimpleEntry::getKey, toList())));
    
  2. # 2 楼答案

    我不确定,但看起来你真正想做的更像

    Map<X,Y> result = myList.stream()
        .collect(groupingBy(t -> t.getSomething(),
             reducing(null, t -> t.getSomeOtherThing(), (a,b) -> getFinalDecision(b,a) )));
    

    其中XgetSomething()的返回类型YgetSomeOtherThing()resp的返回类型getFinalDecision(…)。当然,如果XY是同一类型,它也可以工作

    这模仿了原始代码中最初为空的映射的行为,导致null作为第二个参数传递给getFinalDecision以获得每个不同键的第一次出现。然后,第二个参数将是该键上一次getFinalDecision求值的结果

    可能您的旧代码的行为只是一种妥协,所以我将提到另一种选择。当你使用

    Map<X,Y> result = myList.stream()
        .collect(groupingBy(t -> t.getSomething(), mapping(t -> t.getSomeOtherThing(),
            collectingAndThen(reducing((a,b) -> getFinalDecision(a,b)), Optional::get))));
    

    该值最初将是每个不同键的第一次getSomeOtherThing()调用的结果,并且getFinalDecision仅当该键出现多个时才会被调用。因此,第二个参数不会是null,除非getFinalDecision本身在上一次计算中返回null