从流中收集连续对

从流中收集连续对

给定一个流,如{ 0, 1, 2, 3, 4 },

我如何才能最优雅地将它转化为给定的形式:

{ new Pair(0, 1), new Pair(1, 2), new Pair(2, 3), new Pair(3, 4) }

(当然,假设我已经定义了类对)?

编辑:严格地说,这并不是关于INT或原始流的。对于任何类型的流,答案都应该是通用的。


ABOUTYOU
浏览 322回答 3
3回答

侃侃尔雅

我的StreamEx扩展标准流的库提供了一个pairMap方法,用于所有流类型。对于基本流,它不改变流类型,但可以用于进行一些计算。最常见的用法是计算差异:int[]&nbsp;pairwiseDiffs&nbsp;=&nbsp;IntStreamEx.of(input).pairMap((a,&nbsp;b)&nbsp;->&nbsp;(b-a)).toArray();对于对象流,可以创建任何其他对象类型。我的库不提供任何新的用户可见数据结构,例如Pair(这是图书馆概念的一部分)。但是如果你有自己的Pair类并希望使用它,您可以执行以下操作:Stream<Pair>&nbsp;pairs&nbsp;=&nbsp;IntStreamEx.of(input).boxed().pairMap(Pair::new);或者如果你已经有了一些Stream:Stream<Pair>&nbsp;pairs&nbsp;=&nbsp;StreamEx.of(stream).pairMap(Pair::new);此功能是使用自定义分配器..它具有相当低的开销,可以很好地并行化。当然,它适用于任何流源,而不只是随机访问列表/数组,就像许多其他解决方案一样。在许多测试中,它的性能非常好。这是JMH基准测试,在该基准测试中,我们使用不同的方法在较大值之前找到所有输入值(请参见这,这个问题)。

至尊宝的传说

Java 8流库主要用于将流分割成较小的块进行并行处理,因此有状态管道阶段非常有限,并且不支持获取当前流元素的索引和访问相邻的流元素。当然,解决这些问题的一个典型方法是按索引驱动流,并依赖于在一些随机访问数据结构中处理的值,比如ArrayList,从中可以检索元素。如果值在arrayList,可以根据请求生成对,方法如下:&nbsp;&nbsp;&nbsp;&nbsp;IntStream.range(1,&nbsp;arrayList.size()) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.mapToObj(i&nbsp;->&nbsp;new&nbsp;Pair(arrayList.get(i-1),&nbsp;arrayList.get(i))) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.forEach(System.out::println);当然,限制是输入不能是无限流。不过,这个管道可以并行运行。

温温酱

这不是一种优雅的解决方案,它是一种简单的解决方案,但适用于无限流Stream<Pair>&nbsp;pairStream&nbsp;=&nbsp;Stream.iterate(0,&nbsp;(i)&nbsp;->&nbsp;i&nbsp;+&nbsp;1).map(&nbsp;//&nbsp;natural&nbsp;numbers &nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;Function<Integer,&nbsp;Pair>()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Integer&nbsp;previous; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Pair&nbsp;apply(Integer&nbsp;integer)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pair&nbsp;pair&nbsp;=&nbsp;null; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(previous&nbsp;!=&nbsp;null)&nbsp;pair&nbsp;=&nbsp;new&nbsp;Pair(previous,&nbsp;integer); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;previous&nbsp;=&nbsp;integer; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;pair; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}).skip(1);&nbsp;//&nbsp;drop&nbsp;first&nbsp;null现在,您可以将您的流限制在您想要的长度。pairStream.limit(1_000_000).forEach(i&nbsp;->&nbsp;System.out.println(i));P.S.我希望有更好的解决方案,比如Clojure(partition 2 1 stream)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java