use*_*465 9 lambda java-8 java-stream
假设我有一个'A'列表
List<A> as;
Run Code Online (Sandbox Code Playgroud)
如果我想对每个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)?
Run Code Online (Sandbox Code Playgroud)
我在lambda链中失去了对'a'的引用.有没有办法存储它并返回它或什么?
如果您有更复杂的场景或由于某种原因不喜欢@Aaron答案,您可以执行flatMap-capture技巧,为每个外部元素创建一个元素流:
as.stream().
flatMap(a -> Stream.of(a.getX()).
filter(x -> x != null).
map(x -> a)).
forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
在这里,我们嵌套的每个元素的流在这里你可以做任何无国籍流操作(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".
Run Code Online (Sandbox Code Playgroud)
或两个过滤器:
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"
Run Code Online (Sandbox Code Playgroud)
当然,这些简单的场景可以像@Aaron建议的那样重写,但在更复杂的情况下,flatMap-capture可能是合适的解决方案.
我不知道您是否可以访问未修改的元素,但您可以通过以下方式重新设计您的操作链:
as.stream()
.filter(a -> a.getX() != null)
.forEach(a -> a.setLookedUpVal(lookup.get(a.getX()))
Run Code Online (Sandbox Code Playgroud)
现在我明白它会使事情变得更加复杂,并且可能对解决您的现实问题没有兴趣。
然而,它具有与 a 一起工作的优点Stream<A>,在某些情况下,这比在不同步骤使用不同类型更简单且更具可扩展性。