【问题标题】:Java 8: Executing reduce operation on StreamJava 8:对 Stream 执行 reduce 操作
【发布时间】:2017-11-06 20:01:06
【问题描述】:

我有一个 java.util.stream.Stream 包含键值对,例如:

<1,3> <1,5> <3,1> <4,2> <4,7> <4,8>

现在我想合并所有具有相同键的条目:

<1,[3,5]>  <3,[1]> <4,[2,7,8]>

数据已经排序,所以只需要合并连续的数据集。

现在我正在寻找一种方法来像上面一样转换流的内容,而无需将所有数据集加载到内存中。

我希望得到一个 java.util.stream.Stream 作为结果,它具有包含值列表而不是单个值的不同对象类型。

我唯一的方法是自定义迭代器,它执行合并,但转换为迭代器并返回流似乎很难看。

最好的方法是什么?

【问题讨论】:

  • 您已经找到了可能是最好的可用选项。 Stream 并不真正适用于您想要的那种操作。
  • 我认为.groupBy() 操作可能会起作用,具体取决于流中的确切内容。不过,@LouisWasserman 可能更了解您的要求。
  • @KevinO,OP 明确表示他们不想要 a Stream 结果,并避免将数据加载到内存中。 groupingBy 不会让你这样做。
  • @tsolakp 如果我的理解是正确的:OP 已经有办法将其数据库结果集转换为流。他只是不想将所有结果集加载到内存中以获得结果(天真地使用stream.groupBy() 会产生这种讨厌的效果)
  • @Andreas:SpliteratorIterator丑。它更简单。

标签: java java-8 java-stream reduce


【解决方案1】:

这是SteamEx的解决方案。

int[][] datasets = { { 1, 3 }, { 1, 5 }, { 3, 1 }, { 4, 2 }, { 4, 7 }, { 4, 8 } };

StreamEx.of(datasets) //
        .collapse((a, b) -> a[0] == b[0], groupingBy(a -> a[0], mapping(a -> a[1], toList()))) //
        .forEach(System.out::println);

您可以将int[] 替换为您的dataset 对象。我们可以添加peek来验证它是否是延迟加载/计算:

StreamEx.of(datasets) //
        .peek(System.out::println) //
        .collapse((a, b) -> a[0] == b[0], groupingBy(a -> a[0], mapping(a -> a[1], toList()))) //
        .limit(1) //
        .forEach(System.out::println);

【讨论】:

    猜你喜欢
    • 2015-08-29
    • 2018-03-03
    • 1970-01-01
    • 2014-08-14
    • 1970-01-01
    • 2019-11-01
    • 2015-07-07
    • 1970-01-01
    相关资源
    最近更新 更多