【问题标题】:Storing/Reusing intermediate results on a java 8 stream在 java 8 流上存储/重用中间结果
【发布时间】:2018-03-11 21:51:40
【问题描述】:

我有一个 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)

【问题讨论】:

    标签: java java-8 java-stream


    【解决方案1】:

    你总是可以传递两个包裹在Pair、array、List 中的东西,例如:

    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 */)
    

    【讨论】:

      【解决方案2】:

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

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

      您不需要围绕流元素创建包装器。 load 方法将只执行一次,以防它是一个昂贵的操作。

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

      【讨论】:

      • 或.flatMap(a -&gt; { B b = load(a); return filter(a, b)? Stream.of(b): null; })
      • @Holger,是的,它更好
      【解决方案3】:

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

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

      请注意,当它是完美有效的 Java 8 代码时,一些 IDE 不接受它。

      【讨论】:

      • 我花了一段时间才弄清楚那行是匿名类创建,有 2 个字段(尽管我喜欢这些事情并且有时会这样做)
      • ...x.a...x.b... 不是一个有效的语法,你能把它放在评论中吗?
      猜你喜欢
      • 2015-09-02
      • 2015-06-29
      • 1970-01-01
      • 2015-10-21
      • 2014-11-11
      • 2017-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多