• 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

Lambda expressions in Plain English

 
Ranch Hand
Posts: 228
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Let us consider the following code:



I'm shaky on my understanding of this expression, so I will attempt to dumb it down. In English, we would say:

"Hey Mr. Compiler! I want to create an object called "comparator," which is of type "Comparator<String>".
The -> (arrow operator) is simply shorthand for  the curly braces and semi-colon to denote the anonymous class and the return statement.
In the past, we would have had a "compare" method inside an anonymous class body, which took 2 parameters: "String s1, and String s2", but this was redundant, since we
are only interested what this anonymous method is returning. So, in essence, we are now also declaring an anonymous method!

So now, the above code will give us an object called comparatorObject, which will primarily (exclusively?) be used as an argument to some method. How? why? I'm not sure... but I imagine
that this method which is expecting to receive comparatorObject as an argument, "knows" that these comparatorObjects contain anonymous methods, which will give a return type, which it will do something with.

Am I right on all points? I still feel I'm lost on how this comparatorObject will be "consumed" by the receiving method, so if someone can please dumb it down for me and explain it step-by-step in the above style? Thank you!


 
Marshal
Posts: 79177
377
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mark Richardson wrote:. . . "Hey Mr. Compiler! I want to create an object called "comparator," which is of type "Comparator<String>".

Yes, correct; that is the declaration part of the line, i.e. that part left of the assignment operator =.

The -> (arrow operator) is simply shorthand for  the curly braces and semi-colon to denote the anonymous class and the return statement.

Nearly, but not quite. If you write an anonymos class, you get a file called MyClass$1.class created, but you don't get such a file for a λ. A λ isn't quite equivalent to an anonymous class. For another thing, a λ can only have one method declared (or not declared), viz. the functional method declared in its documentation (example).

In the past, we would have had a "compare" method inside an anonymous class body, which took 2 parameters: "String s1, and String s2", but this was redundant, since we
are only interested what this anonymous method is returning. So, in essence, we are now also declaring an anonymous method!

No, you are declaring the implementation for the functional method (here compare(T, T)). What you are declaring is the parameters to the left of the -> and the expression to be returned (not a return statement) to the right of the -> operator. It is possible to declare one or more statements as the method body, but the syntax is different. You will find out that you can omit the types for the parameters in about 95% of cases, this present one included.

So now, the above code will give us an object called comparatorObject, which will primarily (exclusively?) be used as an argument to some method.

Objects don't have names; that would be the identifier you are applying to its reference, but it has changed since the beginning of your post

. . . this method which is expecting to receive comparatorObject as an argument, "knows" that these comparatorObjects contain anonymous methods . . .

No, it receives an object which it “knows” will implement the Comparator<String> interface. It “knows” that the functional method compare(T, T) has been implemented, and that is what it will use. It doesn't “know” whether that object was made from a named class, anonymous class or a λ, and it doesn't care about any of that.
It gives its own name to the reference, which in the case of List#sort() is c.

I still feel I'm lost on how this comparatorObject will be "consumed" by the receiving method . . .

You have assigned that Comparator object to a reference; you can therefore use that reference as long as it remains in scope. The object is used by the method, not consumed by it.
You could create that object inside the () of a method call, in which case you don't usually retain a reference to it, and then you could only use that object once.
 
M Richardson
Ranch Hand
Posts: 228
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you for that line by line explanation!
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That's a pleasure
 
reply
    Bookmark Topic Watch Topic
  • New Topic