2017-06-05 83 views
5

操作我有包含像键值对的java.util.stream.Stream:的Java 8:执行减少流

<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作为结果与一个不同的对象类型包含值的列表,而不是一个单一的值。

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

它的最佳方法是什么?

+6

你已经找到了可能是最好的选择。流并不是真正意义上的你想要的那种操作。 –

+0

我认为'.groupBy()'操作可能会正常工作,具体取决于流中的内容。然而@LouisWasserman可能会更好地理解你的要求。 – KevinO

+0

@KevinO,OP专门表示他们不希望将Stream作为结果,并且避免将数据加载到内存中。 'groupingBy'不会让你这样做。 –

回答

4

这是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); 

你可以用你dataset对象替换int[]。我们可以添加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);