This week's book giveaway is in the Jython/Python forum.
We're giving away four copies of Murach's Python Programming and have Michael Urban and Joel Murach on-line!
See this thread for details.
Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Method references  RSS feed

 
srinivas pichuka
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I was trying to understand the memory references, while using the for loop on arraylist. But have few question on it. Please find the code below.



The above code prints me the output as "AAA  BBB". But if you see the commented section, the return type is of type Function.
When, I went into the ArrayList foreach implementation, I see the following code.



By the code it means, that the forEach of an ArrayList accepts the input as Consumer.  

I was confused and not able to understand, how my code which is of type Function, is being processed by the forEach loop which accepts Consumer as the input.


Could anybody, please clarify me on this.
 
Pierre-Yves Saumont
Author
Ranch Hand
Posts: 98
17
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When you write:



You are declaring a method reference and giving it the type Function<String, String>.

But this::printMe by itself has no specified type. If the type is not specified, it is inferred (if possible).

stringList.forEach() expects an argument of type Consumer<String>. As the method reference has a compatible type, the correct type is inferred.

Using the Consumer type is simply ignoring the return value.

You could write this as



Here, c is using the same method reference as s in you example, but with a different type.

But note that there is absolutely no relation between Consumer and Function. If you were to write this example in Java 7, you would end with:




The common part is Main.this.printMe(str);, which is what the method reference refers to.

But don't think the method reference is a different way to create anonymous classes. It is not. No classes are actually created nor instantiated.

If you want to learn about functions in more details: Functional Programming in Java



 
Campbell Ritchie
Sheriff
Posts: 53720
127
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Did you really write, “memory referenceces”? I presume that is a spelling error for method references.
 
Pierrot Mongonnam
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dear @Pierre-Yves Saumont, your assertion ...As the method reference has a compatible type, the correct type is inferred.... Now I'm totally confused. I understood that in Java 8, a Consumer<String> has a Functor String -> void. So the printMe Method has the Functor String  -> String. So now I don't really see any compatibility?!?! or the method reference is to understand differently, which means I didn't understand what a method reference is? Thank you for a response.
 
srinivas pichuka
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Pierre-Yves Saumont,

Thank you for the response. It gave me a better detail, on how to think of method reference. I think i need to go through the book reference, which you have provided, to get a  better idea. Thank You. :-)
 
srinivas pichuka
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Campbell Ritchie,

Yes it is method reference only. It's a typo.
 
Stephan van Hulst
Saloon Keeper
Posts: 6966
109
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Pierrot, a (String -> String) can be passed to a higher order function that accepts a (String -> void), because the higher order function is allowed to ignore the return type.

You can not explicitly pass a Function<String, String> to a method that accepts a Consumer<String>, but when you pass a lambda or a method handle, the compiler will infer that the type is Consumer<String>, because (String -> String) is compatible with (String -> void).

 
Pierrot Mongonnam
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan, many, many thanks! I started to doubt about my understanding because I spent many time on this paradigm. This was a very very cool explanation!!!
 
salvin francis
Bartender
Posts: 1479
21
Eclipse IDE Google Web Toolkit Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:You can not explicitly pass a...

A really good explanation, here's a cow.
I too am trying to get my head around these concepts. Somehow they seem cryptical to me
 
Stephan van Hulst
Saloon Keeper
Posts: 6966
109
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Salvin!

The important part is that Java's type system will NEVER allow you to assign an object reference of one type to a variable of an incompatible type. This is good, it allows us to reason about our programs in the same way we did before Java 8.

The trick is that method references and lambdas don't have a type of their own. Their type is determined by the context they are used in:

 
Randall Twede
Ranch Hand
Posts: 4583
6
Java Python Scala
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
all this new stuff looks a lot like what I have been learning about scala
 
srinivas pichuka
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Stephan: Thank You.  As you have mentioned, when there is string->string, then  in higher order functions, we can also give as string->void, as higher order functions can skip the return type.    Would like to know if there are any other rules like this, related to higher order functions.  As to know this rule, it took me a long time...and your answer gave me a clarity that this rule exists.
 
Stephan van Hulst
Saloon Keeper
Posts: 6966
109
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
srinivas pichuka wrote:As you have mentioned, when there is string->string, then  in higher order functions, we can also give as string->void, as higher order functions can skip the return type.

What you wrote is ambiguous.

When a higher order function accepts a function (a -> void), where a denotes one or more parameters of any type, you may pass a function (a -> *), where * denotes any return type.

I can't think of any similar rules in Java. The void return type is pretty exceptional, because it's not usually used in functional programming. In a language like Haskell, (a -> void) would be either (a -> *) or simply a, depending on what you want the higher order function to do. Languages like Haskell don't have analogues to Consumer, because functions must always have a return type.
 
srinivas pichuka
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Got it.. :-)
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!