Java method reference new

Ссылки на методы

Если лямбда выражения вызывают только один существующий метод, лучше ссылаться на этот метод по его имени. Ссылки на методы (Method References) – это компактные лямбда выражения для методов у которых уже есть имя. Например:

Consumer consumer = str -> System.out.println(str); 

можно переписать с помощью method references:

Consumer consumer = System.out::println;

Ссылки на методы бывают четырех видов:

Ссылка на статический метод

Ссылка на нестатический метод конкретного объекта

Ссылка на нестатический метод любого объекта конкретного типа

2. Ссылка на статический метод

ContainingClass::staticMethodName
Function function = e -> Boolean.valueOf(e); System.out.println(function.apply("TRUE")); 

Перепишем с помощью ссылки:

Function function = Boolean::valueOf; System.out.println(function.apply("TRUE"));

3. Ссылка на нестатический метод конкретного объекта

containingObject::instanceMethodName

Этот тип используется когда лямбда выражение вызывает метод внешнего уже существующего объекта.

Consumer consumer = e -> System.out.println(e); consumer.accept("OCPJP 8");

Перепишем, используя ссылку:

Consumer consumer = System.out::println; consumer.accept("OCPJP 8");
Integer integer = 5; Supplier supplier = () -> integer.toString(); System.out.println(supplier.get());
Integer integer = 5; Supplier supplier = integer::toString; System.out.println(supplier.get());

4. Ссылка на нестатический метод любого объекта конкретного типа

Function function = s -> s.toLowerCase(); System.out.println(function.apply("OCPJP 8"));
Function function = String::toLowerCase; System.out.println(function.apply("OCPJP 8"));

5. Ссылка на конструктор

ClassName не может быть абстрактным классом или интерфейсом.

Function function = (d) -> new Integer(d); System.out.println(function.apply("4"));
Function function = Integer::new; System.out.println(function.apply("4"));

Источник

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 .

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

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

Источник

Java 8 Method reference

Java 8 Method reference

Java 8 has introduced a lot of new features such as lambda expressions, stream, Method references etc.

In this post, we will see what are Method references and how can we use it. I will try to provide more examples rather than theory.

Introduction to Method Reference

Method references are special types of lambda expressions that execute only one method.
General syntax of method reference:

You might have already guessed that you need to understand lambda expressions first. If you are comfortable with lambda expressions, then let’s move forward.

Let’s understand this with the help of example.
Let’s create class MethodReferecesLambdaExpressionMain in which we are going to print list using stream’s foreach method.

stream.foreach() method takes consumer functional interface as agrument.

Consumer is functional interface that takes a single argument and returns nothing.
We have used consumer functional interface in 3 ways.

You might already know that you can use lambda expression instead of an anonymous class, but You can use method reference only when the lambda expression just calls to a method.

So if you look at below syntax:

In method reference, we have Class or object before :: and method name after :: without arguments.

Did you notice the method reference does not have arguments?
Yes, we don’t need to pass arguments to method reference, arguments are passed automatically internally based on type of method reference.

The below diagrams will make it clearer.
You can use method reference as below:

MethodReference

Let’s say you want to convert country to uppercase before printing it. You can achieve it using anonymous class and lambda expression but not with method reference.

You can not use method reference as below:

MethodReferenceNot

You can obviously use the stream’s map() method to convert the country to uppercase before printing it. I just want to demonstrate when method reference can’t be used.

Types of method references

There are four types of method references.

  1. Reference to static method
  2. Reference to instance method of object type
  3. Reference to instance method of existing object
  4. Reference constructor

Reference to static method

When you have lambda expression which calls to static method, then you can method reference to static method.

Lambda expression syntax
(args) -> ClassName.someStaticMethod(args)
can be converted to
ClassName::someStaticMethod

Let’s see this with the help of example.

Create a class name PowerFunctions

Источник

Читайте также:  Java script по кругам
Оцените статью