lambda - 在 java 8 lambdas 中,如何访问流中的原始对象?

标签 lambda java-8 java-stream

假设我有一个“A”列表

List<A> as;

如果我想对每个 A 进行相当多的处理,并且在处理结束时,我想将结果放入 A 的另一个字段中,那么最好的方法是什么?


as.stream().
map(a -> a.getX()).
filter(x -> x != null).
map(x -> lookup.get(x)).

At this point how to say y -> a.setLookedUpVal(y)?

我在 lambda 链中失去了对 'a' 的进一步引用。有没有办法存储它并引用它或其他什么?

最佳答案

如果您有更复杂的场景或由于某种原因不喜欢@Aaron 的回答,您可以执行 flatMap 捕获技巧,为每个外部元素创建一个元素流:

as.stream().
   flatMap(a -> Stream.of(a.getX()).
      filter(x -> x != null).
      map(x -> a)).
   forEach(System.out::println);

在这里,我们嵌套了每个元素的流,您可以在其中执行任何无状态流操作( mapfilterpeekflatMap )并引用原始元素。原始元素变得不必要后,您关闭 flatMap并继续原始流。示例:
Stream.of("a", "bb", "ccc", "dd", "eeee")
    .flatMap(a -> Stream.of(a.length())
            .filter(x -> x > 2)
            .map(x -> a))
    .forEach(System.out::println);
// prints "ccc" and "eeee".

或两个过滤器:
Stream.of("a", "bb", "ccc", "dd", "eeee")
    .flatMap(a -> Stream.of(a.length())
            .filter(x -> x > 2)
            .map(x -> a.charAt(0)) // forget the length, now check the first symbol
            .filter(ch -> ch == 'c')
            .map(x -> a)) // forget the first symbol, reverting to the whole string
    .forEach(System.out::println);
// prints only "ccc"

当然,这种简单的场景可以像@Aaron 建议的那样重写,但在更复杂的情况下,flatMap-capturing 可能是合适的解决方案。

关于lambda - 在 java 8 lambdas 中,如何访问流中的原始对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37299312/

相关文章:

random - Pyspark - 在特定列上运行的 Lambda 表达式

java - 根据另一个列表流式传输和过滤一个列表

java - 通过流和平面图传递对象

java - 仅使用两个键和奇数或偶数列表索引作为值将 List 转换为 Map - Java 8 Stream

java - 如何将包含字符串列表(内部列表)的对象列表转换为字符串列表

c# - 从 Func<bool, T> 或类似的 lambda 中提取信息

c++ - 使用 lambda 函数对 STL 容器进行排序

C++;使用 lambda 有条件地扩展类中的函数(MWE 的段错误)

java - Future.cancel() 后跟 Future.get() 杀死我的线程

java - 如何在 java 流中映射超过 1-1 条记录?