Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why Java 8 :: operator not working for Object hashcode method when we use super?

Tags:

java

java-8

Below code working

Function fun1= super::equals
Function fun2= Object::hashCode 

But below code is not

Function fun1= Object::equals
Function fun2= super::hashCode 

What is the concept here even though all are instance methods in Object class.

I have read somewhere the principals are:

  1. object::instance methods
  2. Class::static method
  3. Class:: instance Method
like image 629
Balraj goud Avatar asked Feb 20 '19 12:02

Balraj goud


3 Answers

The Function interface is a functional interfaces representing a function that accepts one parameter and returns a value.

super::equals works because it is a function that accepts one parameter and returns a value.

Object::equals does not work because it is a function that accepts two parameters and returns a value.

If you have a method reference of the form ClassName::instanceMethod, the function that it represents will have an extra parameter - the object on which to call the method. According to the docs:

The equivalent lambda expression for the method reference String::compareToIgnoreCase would have the formal parameter list (String a, String b), where a and b are arbitrary names used to better describe this example. The method reference would invoke the method a.compareToIgnoreCase(b)

super::equals is of the form instance::instanceMethod so there is no problem and works as you expect.

The correct functional interface types to use for Object::equals and super::hashCode is BiFunction<Object, Object, Boolean> and IntSupplier.

Also, don't use raw types.

like image 136
Sweeper Avatar answered Nov 14 '22 22:11

Sweeper


When you write super::methodName, you are creating a method reference on a specific instance of a class. Therefore, the method of the functional interface (that you assign this method reference to) must expect the same number of parameters as methodName has.

When you write ClassName::methodName, if methodName is not a static method, you are creating a method reference on an arbitrary instance of a class. Therefore, the method of the functional interface (that you assign this method reference to) must expect the same number of parameters as methodName has + 1 (the extra parameter being the instance of ClassName on which the method will be executed).

Function takes one argument and returns a value.

Hence you can assign to it a method reference of a specific instance and a single argument method (as in super::equals) or a method reference of an arbitrary instance and a 0 argument method (as in Object::hashCode).

You can't, however, assign to it a method reference of an arbitrary instance and a single argument method (as in Object::equals), since that requires two arguments, and Function expects just one.

Since two arguments are expected, you can assign this method reference to a BiFunction:

BiFunction<Object,Object,Boolean> bifunc = Object::equals;

Similarly, you can't assign to it a method reference of a specific instance and a 0 argument method (as in super::hashCode), since that requires 0 arguments, and Function expects one.

Since 0 arguments are expected, you can assign this method reference to a Supplier:

Supplier<Integer> sup = super::hashCode;
like image 32
Eran Avatar answered Nov 14 '22 22:11

Eran


java.util.Function is a function which takes one argument.

super::equals is a function which takes one argument (the object which is super compared to), hence it works. Object::equals is a function which takes two arguments: the target object and the object to compare to, hence it doesn't work.

Similarly, Object::hashCode is a function of one argument, but super::hashCode is a function of zero arguments.

like image 39
Alex Shesterov Avatar answered Nov 14 '22 22:11

Alex Shesterov