在java8中,如何在lambdas foreach块中设置全局值? 公共无效测试(){ 字符串x; 列表=数组。asList(“a”、“b”、“c”、“d”); 列表。forEach(n->{ 如果(n等于(“d”)) x=“匹配值”; }); }
1.像上面的代码一样,我想在foreach块旁边设置一个变量的值,它可以工作吗 2.为什么 3.foreach迭代器是有序的还是无序的 4.我认为lamdas foreach块对于迭代器来说既酷又简单,但这确实是一件复杂的事情,而不是java 7或之前的工作在java8中,如何在lambdas foreach块中设置全局值? 公共无效测试(){ 字符串x; 列表=数组。asList(“a”、“b”、“c”、“d”); 列表。forEach(n->{ 如果(n等于(“d”)) x=“匹配值”; }); },java,foreach,lambda,java-8,Java,Foreach,Lambda,Java 8,1.像上面的代码一样,我想在foreach块旁边设置一个变量的值,它可以工作吗 2.为什么 3.foreach迭代器是有序的还是无序的 4.我认为lamdas foreach块对于迭代器来说既酷又简单,但这确实是一件复杂的事情,而不是java 7或之前的工作 不,你不能这么做。(虽然你应该自己试试) 因为匿名内部类和lambda表达式中使用的变量必须是有效的final 使用filter和map可以更简洁地实现同样的效果 public void test(){ String
有效的final
李>
filter
和map
可以更简洁地实现同样的效果
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";
});
}
可选d=list.stream()
.filter(c->c.equals(“d”))
.findFirst()
.map(c->“匹配值”);
如前所述,您不能从lambda主体(以及匿名类主体)修改外部方法的局部变量。我的建议是,当lambdas完全不必要时,不要尝试使用它们。您的问题可以这样解决:
Optional<String> d = list.stream()
.filter(c -> c.equals("d"))
.findFirst()
.map(c -> "match the value");
公共无效测试(){
字符串x;
列表=数组。asList(“a”、“b”、“c”、“d”);
如果(列表包含(“d”))
x=“匹配值”;
}
通常,lambda是函数式编程的朋友,在函数式编程中,很少有可变变量(每个变量只分配一次)。如果您使用lambdas,但继续以命令式方式思考,您将始终遇到此类问题。当然,您可以通过以下技巧“使外部值可变”:
public void test(){
String x;
List<String> list = Arrays.asList("a","b","c","d");
if(list.contains("d"))
x = "match the value";
}
公共无效测试(){
字符串[]x=新字符串[1];
列表=数组。asList(“a”、“b”、“c”、“d”);
列表。forEach(n->{
如果(n等于(“d”))
x[0]=“匹配值”;
});
}
不过,要做好准备,迎接团队中功能纯粹主义者的打击。然而,更好的方法是使用更实用的方法():
公共无效测试(){
列表=数组。asList(“a”、“b”、“c”、“d”);
字符串x=list.stream()
.filter(“d”::等于)
.findAny()
.map(v->“匹配值”)
.orElse(空);
}
除了已经提供的惯用示例外,另一个技巧是使用AtomicReference,但我仅在您确实需要“forEach”并且更喜欢比真正的函数变体更可读的东西时推荐它:
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);
}
公共无效测试(){
AtomicReference x=新的AtomicReference();
列表=数组。asList(“a”、“b”、“c”、“d”);
列表。forEach(n->{
如果(n等于(“d”))
x、 设置(“匹配值”);
});
}
if(list.stream().filter(“d”):equals.findAny().isPresent())x=“匹配值”可以替换(例如)您的循环代码>。在大多数情况下,都有一种编写代码的方法,而不必操作外部变量。@assylias:if(list.stream().anyMatch(“d”::equals”)…
或if(list.contains(“d”)…
@Holger Argh-我总是忘记这个方法(anyMatch),是的,它包含的内容甚至更好。谢谢每个人都用好的旧的。@谢谢。事实上,我想解决这个问题。作为旁注,您的代码确实与OP的代码相匹配,因为x
之后完全没有用处,因为可能没有分配。尽管我不建议foreach使用它,但只对AtomicReference
进行了投票。相反,如果用于并行流,这种方法是有意义的。不能推荐为一些可以用传统循环直接完成的事情发明一个高度复杂的函数构造。@RalfKleberhoff:随你的便。
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);
}
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");
});
}