Movatterモバイル変換


[0]ホーム

URL:


Documentation

The Java™ Tutorials
Classes and Objects
Classes
Declaring Classes
Declaring Member Variables
Defining Methods
Providing Constructors for Your Classes
Passing Information to a Method or a Constructor
Objects
Creating Objects
Using Objects
More on Classes
Returning a Value from a Method
Using the this Keyword
Controlling Access to Members of a Class
Understanding Class Members
Initializing Fields
Summary of Creating and Using Classes and Objects
Questions and Exercises
Questions and Exercises
Nested Classes
Inner Class Example
Local Classes
Anonymous Classes
Lambda Expressions
Method References
When to Use Nested Classes, Local Classes, Anonymous Classes, and Lambda Expressions
Questions and Exercises
Enum Types
Questions and Exercises
Trail: Learning the Java Language
Lesson: Classes and Objects
Section: Nested Classes
Subsection: Lambda Expressions
Home Page >Learning the Java Language >Classes and Objects
« Previous • Trail • Next »

The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.
SeeDev.java for updated tutorials taking advantage of the latest releases.
SeeJava Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.
SeeJDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.

Method References

You uselambda 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 thePerson class discussed in the sectionLambda 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 exampleMethodReferencesTest):

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

The method signature of this invocation ofsort is the following:

static <T> void sort(T[] a, Comparator<? super T> c)

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

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

However, this method to compare the birth dates of twoPerson instances already exists asPerson.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 referencePerson::compareByAge is semantically the same as the lambda expression(a, b) -> Person.compareByAge(a, b). Each has the following characteristics:

Kinds of Method References

There are four kinds of method references:

KindSyntaxExamples
Reference to a static methodContainingClass::staticMethodNamePerson::compareByAge
MethodReferencesExamples::appendStrings
Reference to an instance method of a particular objectcontainingObject::instanceMethodNamemyComparisonProvider::compareByName
myApp::appendStrings2
Reference to an instance method of an arbitrary object of a particular typeContainingType::methodNameString::compareToIgnoreCase
String::concat
Reference to a constructorClassName::newHashSet::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> T mergeThings(T a, T b, BiFunction<T, T, T> 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 theSystem.out.println() statements print the same thing:Hello World!

BiFunction is one of many functional interfaces in thejava.util.function package. TheBiFunction 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 referencesPerson::compareByAge andMethodReferencesExamples::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 referencemyComparisonProvider::compareByName invokes the methodcompareByName that is part of the objectmyComparisonProvider. The JRE infers the method type arguments, which in this case are(Person, Person).

Similarly, the method referencemyApp::appendStrings2 invokes the methodappendStrings2 that is part of the objectmyApp. 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 referenceString::compareToIgnoreCase would have the formal parameter list(String a, String b), wherea andb are arbitrary names used to better describe this example. The method reference would invoke the methoda.compareToIgnoreCase(b).

Similarly, the method referenceString::concat would invoke the methoda.concat(b).

Reference to a Constructor

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

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

The functional interfaceSupplier contains one methodget that takes no arguments and returns an object. Consequently, you can invoke the methodtransferElements with a lambda expression as follows:

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

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

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

The Java compiler infers that you want to create aHashSet collection that contains elements of typePerson. Alternatively, you can specify this as follows:

Set<Person> rosterSet = transferElements(roster, HashSet<Person>::new);
« PreviousTrailNext »

About Oracle |Contact Us |Legal Notices |Terms of Use |Your Privacy Rights

Copyright © 1995, 2024 Oracle and/or its affiliates. All rights reserved.

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

[8]ページ先頭

©2009-2025 Movatter.jp