public void test(){
String x;
List list=Arrays.asList(\"a\",\"b\",\"c\",\"d\");
list.forEach(n->{
if(n.equals(\"
As it's already explained, you cannot modify the local variable of the outer method from the lambda body (as well as from the anonymous class body). My advice is don't try to use lambdas when they are completely unnecessary. Your problem can be solved like this:
public void test(){
String x;
List<String> list = Arrays.asList("a","b","c","d");
if(list.contains("d"))
x = "match the value";
}
In general lambdas are friends with functional programming where you rarely have mutable variables (every variable is assigned only once). If you use lambdas, but continue thinking in imperative style you will always have such problems.
You could, of course, "make the outer value mutable" via a trick:
public void test() {
String[] x = new String[1];
List<String> list = Arrays.asList("a", "b", "c", "d");
list.forEach(n -> {
if (n.equals("d"))
x[0] = "match the value";
});
}
Get ready for a beating by the functional purist on the team, though. Much nicer, however, is to use a more functional approach (similar to Sleiman's approach):
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);
}
effectively final
. you can achieve the same more concisely using filter
and map
.
Optional<String> d = list.stream()
.filter(c -> c.equals("d"))
.findFirst()
.map(c -> "match the value");
In addition to already provided idiomatic examples, another hack would be to use AtomicReference, but I would only recommend it if you do need 'forEach' and prefer something more readable than true-functional variant:
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");
});
}