Java reference to class method

Java 8 method reference example

In Java 8, we can refer a method from class or object using class::methodName type syntax. Let’s learn about different types of available method references in java 8.

Table of Contents 1. Types of Method References 2. Reference to static method - Class::staticMethodName 3. Reference to instance method from instance - ClassInstance::instanceMethodName 4. Reference to instance method from class type - Class::instanceMethodName 5. Reference to constructor - Class::new

1. Types of method references

Java 8 allows four types of method references.

Method Reference Description Method reference example
Reference to static method Used to refer static methods from a class Math::max equivalent to Math.max(x,y)
Reference to instance method from instance Refer to an instance method using a reference to the supplied object System.out::println equivalent to System.out.println(x)
Reference to instance method from class type Invoke the instance method on a reference to an object supplied by the context String::length equivalent to str.length()
Reference to constructor Reference to a constructor ArrayList::new equivalent to new ArrayList()

2. Method reference to static method – Class::staticMethodName

An example to use Math.max() which is static method.

List integers = Arrays.asList(1,12,433,5); Optional max = integers.stream().reduce( Math::max ); max.ifPresent(value -> System.out.println(value));

3. Method reference to instance method from instance – ClassInstance::instanceMethodName

In above example, we use System.out.println(value) to print the max value found. We can use System.out::println to print the value.

List integers = Arrays.asList(1,12,433,5); Optional max = integers.stream().reduce( Math::max ); max.ifPresent( System.out::println );

4. Method reference to instance method from class type – Class::instanceMethodName

In this example, s1.compareTo(s2) is referred as String::compareTo .

List strings = Arrays .asList("how", "to", "do", "in", "java", "dot", "com"); List sorted = strings .stream() .sorted((s1, s2) -> s1.compareTo(s2)) .collect(Collectors.toList()); System.out.println(sorted); List sortedAlt = strings .stream() .sorted(String::compareTo) .collect(Collectors.toList()); System.out.println(sortedAlt);
[com, do, dot, how, in, java, to] [com, do, dot, how, in, java, to]

5. Reference to constructor – Class::new

Читайте также:  Font size echo php

The first method can be updated to create a list of integers from 1 to 100. Using lambda expression is rather easy. To create a new instance of ArrayList , we have use ArrayList::new .

List integers = IntStream .range(1, 100) .boxed() .collect(Collectors.toCollection( ArrayList::new )); Optional max = integers.stream().reduce(Math::max); max.ifPresent(System.out::println);

That’s 4 type of method references in java 8 lambda enhancements.

Источник

Method References

You use lambda expressions to create anonymous methods. Sometimes, however, a lambda expression does nothing but call an existing method. In those cases, it’s often clearer to refer to the existing method by name. Method references enable you to do this; they are compact, easy-to-read lambda expressions for methods that already have a name.

Consider again the Person class discussed in the section Lambda Expressions:

public class Person < // . LocalDate birthday; public int getAge() < // . >public LocalDate getBirthday() < return birthday; >public static int compareByAge(Person a, Person b) < return a.birthday.compareTo(b.birthday); >// . >

Suppose that the members of your social networking application are contained in an array, and you want to sort the array by age. You could use the following code (find the code excerpts described in this section in the example MethodReferencesTest ):

Person[] rosterAsArray = roster.toArray(new Person[roster.size()]); class PersonAgeComparator implements Comparator  < public int compare(Person a, Person b) < return a.getBirthday().compareTo(b.getBirthday()); >> Arrays.sort(rosterAsArray, new PersonAgeComparator());

The method signature of this invocation of sort is the following:

static void sort(T[] a, Comparator c)

Notice that the interface Comparator is a functional interface. Therefore, you could use a lambda expression instead of defining and then creating a new instance of a class that implements Comparator :

Arrays.sort(rosterAsArray, (Person a, Person b) -> < return a.getBirthday().compareTo(b.getBirthday()); >);

However, this method to compare the birth dates of two Person instances already exists as Person.compareByAge . You can invoke this method instead in the body of the lambda expression:

Arrays.sort(rosterAsArray, (a, b) -> Person.compareByAge(a, b) );

Because this lambda expression invokes an existing method, you can use a method reference instead of a lambda expression:

Arrays.sort(rosterAsArray, Person::compareByAge);

The method reference Person::compareByAge is semantically the same as the lambda expression (a, b) -> Person.compareByAge(a, b) . Each has the following characteristics:

  • Its formal parameter list is copied from Comparator.compare , which is (Person, Person) .
  • Its body calls the method Person.compareByAge .
Читайте также:  Массив всех символов python

Kinds of Method References

There are four kinds of method references:

Kind Syntax Examples
Reference to a static method ContainingClass::staticMethodName Person::compareByAge
MethodReferencesExamples::appendStrings
Reference to an instance method of a particular object containingObject::instanceMethodName myComparisonProvider::compareByName
myApp::appendStrings2
Reference to an instance method of an arbitrary object of a particular type ContainingType::methodName String::compareToIgnoreCase
String::concat
Reference to a constructor ClassName::new HashSet::new

The following example, MethodReferencesExamples , contains examples of the first three types of method references:

import java.util.function.BiFunction; public class MethodReferencesExamples < public static T mergeThings(T a, T b, BiFunction merger) < return merger.apply(a, b); >public static String appendStrings(String a, String b) < return a + b; >public String appendStrings2(String a, String b) < return a + b; >public static void main(String[] args) < MethodReferencesExamples myApp = new MethodReferencesExamples(); // Calling the method mergeThings with a lambda expression System.out.println(MethodReferencesExamples. mergeThings("Hello ", "World!", (a, b) ->a + b)); // Reference to a static method System.out.println(MethodReferencesExamples. mergeThings("Hello ", "World!", MethodReferencesExamples::appendStrings)); // Reference to an instance method of a particular object System.out.println(MethodReferencesExamples. mergeThings("Hello ", "World!", myApp::appendStrings2)); // Reference to an instance method of an arbitrary object of a // particular type System.out.println(MethodReferencesExamples. mergeThings("Hello ", "World!", String::concat)); > >

All the System.out.println() statements print the same thing: Hello World!

BiFunction is one of many functional interfaces in the java.util.function package. The BiFunction functional interface can represent a lambda expression or method reference that accepts two arguments and produces a result.

Reference to a Static Method

The method references Person::compareByAge and MethodReferencesExamples::appendStrings are references to a static method.

Reference to an Instance Method of a Particular Object

The following is an example of a reference to an instance method of a particular object:

class ComparisonProvider < public int compareByName(Person a, Person b) < return a.getName().compareTo(b.getName()); >public int compareByAge(Person a, Person b) < return a.getBirthday().compareTo(b.getBirthday()); >> ComparisonProvider myComparisonProvider = new ComparisonProvider(); Arrays.sort(rosterAsArray, myComparisonProvider::compareByName);

The method reference myComparisonProvider::compareByName invokes the method compareByName that is part of the object myComparisonProvider . The JRE infers the method type arguments, which in this case are (Person, Person) .

Читайте также:  Html span red font

Similarly, the method reference myApp::appendStrings2 invokes the method appendStrings2 that is part of the object myApp . The JRE infers the method type arguments, which in this case are (String, String) .

Reference to an Instance Method of an Arbitrary Object of a Particular Type

The following is an example of a reference to an instance method of an arbitrary object of a particular type:

String[] stringArray = < "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" >; Arrays.sort(stringArray, String::compareToIgnoreCase);

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) .

Similarly, the method reference String::concat would invoke the method a.concat(b) .

Reference to a Constructor

You can reference a constructor in the same way as a static method by using the name new . The following method copies elements from one collection to another:

public static , DEST extends Collection> DEST transferElements( SOURCE sourceCollection, Supplier collectionFactory) < DEST result = collectionFactory.get(); for (T t : sourceCollection) < result.add(t); >return result; >

The functional interface Supplier contains one method get that takes no arguments and returns an object. Consequently, you can invoke the method transferElements with a lambda expression as follows:

Set rosterSetLambda = transferElements(roster, () -> < return new HashSet<>(); >);

You can use a constructor reference in place of the lambda expression as follows:

Set rosterSet = transferElements(roster, HashSet::new);

The Java compiler infers that you want to create a HashSet collection that contains elements of type Person . Alternatively, you can specify this as follows:

Set rosterSet = transferElements(roster, HashSet::new);

Previous page: Lambda Expressions
Next page: When to Use Nested Classes, Local Classes, Anonymous Classes, and Lambda Expressions

Источник

Оцените статью