流分组值

Stream groupingBy values

是否有 groupingBy 的非终端版本或其他一些巧妙的方式来流式传输生成的 Map entries/values?

我发现自己想要在 groupingBy 之后流式传输值,但我能想到的最好的方法并不漂亮:

    StreamEx.ofValues(
            StreamEx.of(0, 1, 2, 4).groupingBy(i -> i % 2)
    ).mapToInt(ii -> IntStreamEx.of(ii).sum())
    // RESULT: [6, 1]

在单个 Stream 管道中执行此操作可能需要所需的操作像一个完整的屏障:为了对值进行分组,我们需要处理它们以查看哪些值是偶数和奇数(并且能够对它们求和)。

因此,最好使用一个临时数据结构来保存偶数和奇数的计数,在本例中是 Map<Integer, Integer> 甚至是 Map<Boolean, Integer>(其中,例如,对于偶数,键为 true,对于奇数,键为 false,使用 Collectors.partitioningBy).


请注意,您不需要在此处使用 StreamEx 库。您可以直接在 Stream API:

中执行此操作
public static void main(String[] args) {
    Map<Integer, Integer> map =
      Stream.of(0, 1, 2, 4)
            .collect(Collectors.groupingBy(
               i -> i % 2,
               Collectors.summingInt(i -> i)
            ));

    Stream<Integer> stream = map.values().stream();
}

summingInt 可能是这个特定问题的最佳解决方案。

我想我在示例中使用整数将问题简单化了。我的实际问题是关于合并对象,而不是 int 值。我发现 collectingAndThen 非常有用。它是这样工作的:

Function<List<Integer>, Integer> merge = ii -> ii.stream().mapToInt(i -> i).sum();
Stream.of(0, 1, 2, 4).collect(groupingBy(i -> i % 2, collectingAndThen(toList(), merge))).values();