• 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 all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Junilu Lacar
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Knute Snortum
  • Tim Cooke
  • Devaka Cooray
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Piet Souris
  • Frits Walraven
  • Ganesh Patekar

Difference between Lambda and method reference?

 
Ranch Hand
Posts: 1325
1
  • Mark post as helpful
  • send pies
  • 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: 2220
47
IntelliJ IDE Firefox Browser Spring Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is no difference. Both lines do the same thing.
 
Sheriff
Posts: 21802
104
Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
  • Likes 2
  • Mark post as helpful
  • send pies
  • 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: 21802
104
Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • 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: 21802
104
Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
  • Mark post as helpful
  • send pies
  • 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: 10643
227
  • Likes 1
  • Mark post as helpful
  • send pies
  • 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: 21802
104
Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • 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.
 
Get me the mayor's office! I need to tell her about this tiny ad:
Java file APIs (DOC, XLS, PDF, and many more)
https://products.aspose.com/total/java
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!