假设我有一个“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);
在这里,我们嵌套了每个元素的流,您可以在其中执行任何无状态流操作(
map
、 filter
、 peek
和 flatMap
)并引用原始元素。原始元素变得不必要后,您关闭 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/