我想根据某个决定划分一份清单。我还有一张存储这些决策的地图。
目前,我正在更新流中的决定。我觉得这不是好习惯,因为我正在使用收集来做
除了找出分组标准之外的其他操作。我还有另一个选择是再次浏览信息流
并使用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;
}));

最佳答案

我不确定,但是看起来您实际想要做的事情更像

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


其中XgetSomething()的返回类型,而YgetSomeOtherThing()的返回类型。 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

09-26 11:59