public void test(){
String x;
List<String> list=Arrays.asList("a","b","c","d");
list.forEach(n->{
if(n.equals("d"))
x="match the value";
});
}
1.像上面的代码一样,我想在foreach块旁边设置一个变量的值,它可以工作吗?
2.为什么?
3.而foreach迭代器是有序的还是无序的?
4.我认为lamdas foreach块对于迭代器来说很酷且很简单,但这实际上是一件很复杂的事情,而不是java 7或之前的相同工作。
答案 0 :(得分:21)
当然,你可以通过一个技巧“使外部价值变得可变”:
public void test() {
List<String> list = Arrays.asList("a", "b", "c", "d");
String x = list.stream()
.filter("d"::equals)
.findAny()
.map(v -> "match the value")
.orElse(null);
}
准备好让团队中的功能性纯粹主义者挨打。然而,更好的是使用更具功能性的方法(similar to Sleiman's approach):
{{1}}
答案 1 :(得分:8)
effectively final
。 您可以使用filter
和map
更简洁地实现相同目标。
Optional<String> d = list.stream()
.filter(c -> c.equals("d"))
.findFirst()
.map(c -> "match the value");
答案 2 :(得分:8)
除了已经提供的惯用示例之外,另一个黑客将是使用AtomicReference,但我只推荐它,如果你确实需要&#39; forEach&#39;并且更喜欢比真实功能变体更具可读性的东西:
public void test(){
AtomicReference<String> x = new AtomicReference<>();
List<String> list= Arrays.asList("a", "b", "c", "d");
list.forEach(n->{
if(n.equals("d"))
x.set("match the value");
});
}
答案 3 :(得分:6)
正如已经解释的那样,你不能从lambda体(以及匿名类体)修改外部方法的局部变量。我的建议是,在完全没必要的情况下,不要尝试使用lambdas。你的问题可以这样解决:
public void test(){
String x;
List<String> list = Arrays.asList("a","b","c","d");
if(list.contains("d"))
x = "match the value";
}
一般情况下,lambdas是功能编程的朋友,你很少有可变变量(每个变量只分配一次)。如果你使用lambdas,但继续以命令式的方式思考,你总会遇到这样的问题。