• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Difference between Lambda and method reference?

 
Ranch Hand
Posts: 1325
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Below i use lamda and method reference to print values in a list. So what is the difference between two of the methods ?

 
Bartender
Posts: 2236
63
IntelliJ IDE Firefox Browser Spring Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There is no difference. Both lines do the same thing.
 
Sheriff
Posts: 22781
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There is one difference, but it's not easy to see. The lambda is just that - a lambda. The method reference on the other hand is a closure - it captures the current value of System.out. If you would make the lambda / method reference serializable (by casting it to Consumer<Integer> & Serializable), the lambda could work while the method reference would cause serialization errors.

Another difference is the following:

Output:
 
Rob Spoor
Sheriff
Posts: 22781
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
For those interested in how the output is generated:

The first call to process uses a lambda. This means that the flow is as follows:
1) Create the ByteArrayOutputStream.
2) Store the old value of System.out.
3) Replace System.out with a PrintStream wrapping the ByteArrayOutputStream.
4) Call consumer.accept. This will evaluate the current value of System.out - the wrapped ByteArrayOutputStream. The 13 plus line break are therefore added to the ByteArrayOutputStream. Nothing is printed to the old System.out value.
5) System.out is restored.
6) The output in ByteArrayOutputStream is printed. This is the 13 plus line break. This results the first two lines of my output.

The second call to process uses a closure. That means that the flow is as follows:
1) Create the ByteArrayOutputStream.
2) Store the old value of System.out.
3) Replace System.out with a PrintStream wrapping the ByteArrayOutputStream.
4) Call consumer.accept. This will use the closure - println called on the original value of System.out. This is the same as the oldOut variable, not the ByteArrayOutputStream! This results in the third line of my output.
5) System.out is restored.
6) The output in ByteArrayOutputStream is printed. Since nothing was added to it, this is empty. This results in the last line of my output.
 
Rob Spoor
Sheriff
Posts: 22781
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Note that a method reference is only a closure if it's a method reference called on an instance. If the part before the :: is a class name then there would be no difference. For instance, the following pairs are more or less identical (nothing is captured):


 
Saloon Keeper
Posts: 15490
363
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Also note that you can create a closure with lambdas:

This is a closure because it captures a local variable from an enclosing scope. This code should have the same result as the version that uses the method reference.
 
Rob Spoor
Sheriff
Posts: 22781
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Correct. It's a closure when anything is captured, whether that's a local variable or the object on which a method is called. And here's an interesting thing - that also includes the enclosing object or any of its fields that you use.

Consider the following:

When you try to run this, you'll get an exception:

This shows that the enclosing Test instance is captured by the lambda, as it is also being serialised (which causes the exception). Remove the line that accesses "this" and it will work.
 
reply
    Bookmark Topic Watch Topic
  • New Topic