3

I am reading about lambdas from the book Java 8 Lambdas by Richard Warburton. He started out discussion with concurrency in modern CPUs and eventually related lambdas with it. I don't know what I missed but I surely don't get the concept. Consider the following class

class A {

private int state;

A(){
    state = 0;
}

A(int state){
    this.state = state;
}

public int getState() {
    return state;
}

public void setState(int state) {
    this.state = state;
}

@Override
public String toString() {
    return Integer.toString(state);
}
} // end A

public class Main {

public static void main(String[] args) {

    List<A> ls = new ArrayList<>();

    ls.add(new A(2));
    ls.add(new A(3));

    ls.forEach( a -> a.setState(a.getState() + 1) );
    System.out.println(ls); // [3, 4]

} // end main

} // end class Main

How this construct ls.forEach( a -> a.setState(a.getState() + 1) ); is more suitable for concurrent programming than

ls.forEach(new Consumer<A>() {

        @Override
        public void accept(A t) {
            t.setState(t.getState() + 1);
        }
    });
mallaudin
  • 4,744
  • 3
  • 36
  • 68
  • 2
    They are both [pretty much equal](https://stackoverflow.com/questions/22637900/java8-lambdas-vs-anonymous-classes). Apart from that, who told you that `.forEach` on a `ArrayList` will execute in parallel, because it is certainly not true. If you wanted your list to be iterated in parallel, you probably wanted to use `ls.parallelStream().forEach(...)`? – randers Jan 16 '16 at 14:19
  • that's my mistake. I was reading 3rd chapter, that was about Stream API ... I messed up things :/ – mallaudin Jan 16 '16 at 14:29

2 Answers2

5

It's likely that lambdas were not opposed to anonymous class, but internal iteration (using forEach) was opposed to external iteration (using enhanced for loop). In this case it makes sense. External iteration like this just cannot be parallelized:

for(A a : ls) {
    a.setState(a.getState() + 1);
}

In contrast internal iteration is not restricted: if method specification permits (for example, Stream.forEach()) it can parallelized without changing the client code as long as client code obeys some rules (e.g. do not modify shared state). In this sense internal iteration is more concurrency friendly.

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
2

From a developer viewpoint the first lambda example is just expanded by the java compiler to the second code sample you provided. Lambdas basically create an anonymous inner class if and only if the argument to the function requires an interface with one unknown method.

The actual Java8 implementation differs a little bit since they didn't want to generate a ton of classfiles so the implementing classes are created at runtime by binding a private method (the lambda code) with the help of invokedynamic. Some notes from Goetz also mentions that there are some caching optimization oppurtunities possible for the runtime.

Theoretically an optimizing compiler with knowledge of the library implementation could do something clever but that has never been the way java compilers work, mainly because the java source compiler is usually separate from the runtime. (the invokedynamic part does give some oppurtunities but not on a library level)

Stylistically however using the lambda syntax is more terse and could also be viewed as a more clean option as you wouldn't be tempted to insert variables into the inner class containing state.

whizzter
  • 51
  • 3
  • apart from cleaner syntax, is there any other advantage of Lambdas ? – mallaudin Jan 16 '16 at 14:35
  • Apart from cleaner syntax it might be easier to do refactoring if not using an IDE but apart from that since the final compiled code is identical not that much else really. – whizzter Jan 16 '16 at 20:49
  • 3
    It is not correct that “_Technically the first lambda example is just expanded by the java compiler to the second code sample_”. You could say that both are functionally equivalent (from the developer point of view), but technically the lambda will not become an anonymous class. You might even gain some performance improvements with the lambda thanks to those technical differences. – Didier L Jan 17 '16 at 14:33
  • Ah right, went on to read [link](http://wiki.jvmlangsummit.com/images/1/1e/2011_Goetz_Lambda.pdf) and it points out a few benefits of the runtime being able to cache and otherwise decrease allocations in lambdas that inherit little or no state (and the fact that there isn't a need to create a lot of extra class files). Reading it reminded me that i actually read about that earlier in relation to retrolambda. Gonna edit my answer a bit to correct for it. – whizzter Jan 17 '16 at 15:08