What does "an Arbitrary Object of a Particular Type" mean in java 8?
The example given from the Oracle Doc linked is:
String[] stringArray = { "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
The lambda equivalent of
String::compareToIgnoreCase
would be
(String a, String b) -> a.compareToIgnoreCase(b)
The Arrays.sort()
method is looking for a comparator as its second argument (in this example). Passing String::compareToIgnoreCase
creates a comparator with a.compareToIgnoreCase(b)
as the compare method's body. You then ask well what's a
and b
. The first argument for the compare method becomes a
and the second b
. Those are the arbitrary objects, of the type String (the particular type).
Don't understand?
- Make sure you know what a comparator is and how to implement it.
- Know what a functional interface is and how it affects lambdas in Java.
- A comparator is a functional interface that's why the method reference becomes the body of the compare method inside the comparator object.
- Read the source below for another example at the bottom of the page.
Read more at the source: http://moandjiezana.com/blog/2014/understanding-method-references/
It is a reference to an instance method from some type. In the case of the example, compareToIgnoreCase
is a method from String
. The program knows that it can invoke this method on an instance of String
, so it can take the reference and any object of that type and be guaranteed the method exists.
I would compare this to the Method
class in that they refer to a method and can be invoked on an arbitrary instance of some type.
For the example, it can use two String
objects and call compareToIgnoreCase
on one and use the other as an argument to match the method signature. This allows it to take the array and sort it based on any method of the array type instead of requiring a comparator instance to do this instead.
And here is the example for anyone who didn't click on the link in the question:
String[] stringArray = { "Barbara", "James", "Mary", "John",
"Patricia", "Robert", "Michael", "Linda", "George" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
Please see the below code sample which explains "Reference to an Instance Method of an Arbitrary Object of a Particular Type" category described in https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
import java.util.Arrays;
class Person{
String name;
//constructor
public Person(String name){
this.name = name;
}
//instance method 1
public int personInstanceMethod1(Person person){
return this.name.compareTo(person.name);
}
//instance method 2
public int personInstanceMethod2(Person person1, Person person2){
return person1.name.compareTo(person2.name);
}
}
class Test {
public static void main (String[] args) throws Exception{
Person[] personArray = {new Person("A"), new Person("B")};
// Scenario 1 : Getting compiled successfully
Arrays.sort(personArray, Person::personInstanceMethod1);
// Scenario 2 : Compile failure
Arrays.sort(personArray, Person::personInstanceMethod2);
// Scenario 3 : Getting compiled successfully.
Person personInstance = new Person("C");
Arrays.sort(personArray, personInstance::personInstanceMethod2);
// Scenario 4 : Getting compiled successfully. As the same way as "Scenario 1"
String[] stringArray = { "Barbara", "James", "Mary", "John",
"Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
}
}
Scenario 1 and Scenario 4 describes "Reference to an Instance Method of an Arbitrary Object of a Particular Type" category described in https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
If the method parameter takes a variable in same instance Type as the instance Type of the element, you can call that instance method using Type.(Person::personInstanceMethod1)
Compare "personInstanceMethod1" instance method in "Person" class with "compareToIgnoreCase" instance method in "String" class (https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#compareToIgnoreCase-java.lang.String-) to see the similarity. Both are taking a single parameter with the same Type.
Compare Scenario 1 and Scenario 2 to see the difference.