Win a copy of Fixing your Scrum this week in the Agile forum!
  • 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
  • Ron McLeod
  • Paul Clapham
  • Rob Spoor
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • Junilu Lacar
  • Tim Cooke
Saloon Keepers:
  • Tim Holloway
  • Piet Souris
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Frits Walraven
  • Himai Minh

Method Reference in Java 8

 
Ranch Hand
Posts: 35
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Guys Given the below code and the choice of answers are :
a.process(fnames, t::eat);
b.process(fnames, t::calories);
c.process(fnames, TestClass::size);
d.process(fnames, Carnivore::calories);
e.process(fnames, Tiger::eat);

Out of which the correct answers are a,b,c

I understand that a and b are correct but i cannot understand why c is correct. as TestClass is no way related to the carnivores class. Can someone please help me understand the same.

Thanks in advance!!

 
Master Rancher
Posts: 1011
28
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I find this very tricky, and I think I understand method references pretty well.

Not as well as I thought!

TestClass of course, does NOT implement the functional interface Carnivore interface explicitly, which is what we expect to see.
Well, it was what you and I expected to see.  That would have been required if we expected the following to work:

TestClass tc = new TestClass();
process(fnames, tc);


But what TestClass does contain is a method that matches the only real requirement:
int eat(List<String> foods)

More specifically, any lambda that takes a List<String> and returns an int would have compiled and run, I think we both see THAT, right?

This method reference to static method TestClass::size also compiles and runs, because it meets that basic requirement, it takes a  List<String> and returns an int

So the method reference is a valid way to replace the lambda we were easily imagining, despite being a method reference to a class that doesn't implement the Functional Interface explicitly.  The method reference itself is a valid substitute for our lambda.

We could simply pass a Tiger instance in as the second parameter to process(), because a Tiger is a Carnivore (i.e. it implements it)

But a method reference that successfully matches any lambda that could be passed as a parameter somewhere will also compile.

This is kinda tricky!
 
Saloon Keeper
Posts: 4608
182
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Also interesting is the question why "TestClass::size" works, and "Tiger::eat" fails.
 
Jesse Silverman
Master Rancher
Posts: 1011
28
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Piet Souris wrote:Also interesting is the question why "TestClass::size" works, and "Tiger::eat" fails.



Sure, tho in that case it is because despite having the same syntactic form in the reference, Tiger::eat is an instance method reference on an instance to be named later, so at call-time it wants a Tiger implicitly passed as the first parameter (not explicitly) and the List<String> as the second parameter.

Our OP was tricky enough to not be fooled by that one, however.

Might I suggest cross-posting this to "Lambdas and Streams" as well?

It is interesting to those trying to master Method References whether or not they seek certification.
 
Jesse Silverman
Master Rancher
Posts: 1011
28
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Piet Souris wrote:Also interesting is the question why "TestClass::size" works, and "Tiger::eat" fails.



I find this a little tricky too:
       process(fnames, t::calories); // good, because we already gave it 1st parameter right there in the method reference, we only need one more!
       process(fnames, Tiger::calories); // bad, because it lacks an instance on which to call calories()

The error messages in Java 14 for the failed attempt at the second line read:
Cannot make a static reference to the non-static method calories(List<String>) from the type Tiger
The method process(List<String>, Carnivore) in the type TestClass is not applicable for the arguments (List<String>, Tiger::calories)

Method references are very often/usually the shortest way to express a given functional programming construct.
They are NOT always the easiest to see, there is often some interesting stuff going on behind the scenes.
 
This tiny ad is wafer thin:
the value of filler advertising in 2021
https://coderanch.com/t/730886/filler-advertising
reply
    Bookmark Topic Watch Topic
  • New Topic