Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In java8, how to set the global value in the lambdas foreach block?

    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.Like the code above, I want to set the value of a variable beside the foreach block, can it works?

2.And why?

3.And the foreach iterator is in order or disorder?

4.I think the lamdas foreach block is cool and simple for iterator,but this is really a complicated thing to do rather than the same work in java 7 or before.

like image 892
MarsYoung Avatar asked Sep 11 '15 11:09

MarsYoung


2 Answers

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); } 
like image 85
Lukas Eder Avatar answered Sep 19 '22 21:09

Lukas Eder


  1. No you can't do it. (Although you should have tried it yourself)
  2. Because variables used within anonymous inner classes and lambda expression have to be effectively final.
  3. 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"); 
like image 36
Sleiman Jneidi Avatar answered Sep 21 '22 21:09

Sleiman Jneidi