在java 8流上存储/重用中间结果

时间:2018-03-08 20:57:13

标签: java java-8 java-stream

我有一个A的列表,要执行过滤我需要将A映射到B.但是一旦过滤逻辑完成,我仍然需要A进行进一步的操作,所以我的问题是它是否可以实现这一点?我能想到的一种方法是将A和B都存储到第三种类型中,所以我在处理流时都可用,但不确定它是否优雅并且想知道这是否是更好的方法。或者我是否想要适合通过使用溪流在圆孔中的方形钉。

List<A> a;
List<B> b = a.stream().map(i -> load(i)).filter(need A here in addition to b)

3 个答案:

答案 0 :(得分:3)

嗯,你总是可以把两件事包裹成PairarrayList,例如:

a.stream().map(i -> List.of(load(i), i)) // List#of is java-9, replace with Pair or array
          .filter(x -> x[0]...)
          .filter(y -> /* y is List here */)

答案 1 :(得分:1)

这里没有优雅的解决方案,但您可以在映射中进行过滤:

.map(a -> {
    B b = load(a);
    return filter(a, b) ? b : null;
})
.filter(Objects::nonNull)

您不需要在流元素周围创建包装器。 load方法只会在执行昂贵的操作时执行一次。

null是默认的无效值,如果允许null或者可以从load返回,则应将其替换。

答案 2 :(得分:0)

您可以动态使用匿名类(或任何适当的现有类来表示一对或类似对象):

a.stream().map(e -> new Object() { A a=e; B b=load(e); })
          .filter(x -> /*any code using x.a and x.b */)

请注意,某些IDE在完全有效的Java 8代码时并不接受这一点。