假设我有一个'A'列表
List<A> as;
如果我想对每个A进行相当多的处理,并且在处理结束时,我想把结果放在A的另一个字段中,最好的方法是什么?< / p>
即
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'的引用。有没有办法存储它并返回它或什么?
答案 0 :(得分:6)
如果您有更复杂的场景或由于某种原因不喜欢@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-capture可能是合适的解决方案。
答案 1 :(得分:4)
我不知道您是否可以访问未修改的元素,但您可以通过以下方式重新编写操作链:
as.stream()
.filter(a -> a.getX() != null)
.forEach(a -> a.setLookedUpVal(lookup.get(a.getX()))
现在我明白它会使它变得更复杂,并且在解决你的现实问题时可能没什么兴趣
然而,它具有与Stream<A>
一起工作的优点,在某些情况下,它可以比在不同步骤中具有不同类型更简单和更具可扩展性。