In java8, how to set the global value in the lambdas foreach block?
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);
}
- No you can't do it. (Although you should have tried it yourself)
- Because variables used within anonymous inner classes and lambda expression have to be
effectively final
. -
you can achieve the same more concisely using
filter
andmap
.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");
});
}