Method references allow predefined static or instance methods that adhere to a compatible functional interface to be passed as arguments instead of an anonymous lambda expression.
Assume that we have a model:
class Person {
private final String name;
private final String surname;
public Person(String name, String surname){
this.name = name;
this.surname = surname;
}
public String getName(){ return name; }
public String getSurname(){ return surname; }
}
List<Person> people = getSomePeople();
people.stream().map(Person::getName)
The equivalent lambda:
people.stream().map(person -> person.getName())
In this example, a method reference to the instance method getName()
of type Person
, is being passed. Since it's known to be of the collection type, the method on the instance (known later) will be invoked.
people.forEach(System.out::println);
Since System.out
is an instance of PrintStream
, a method reference to this specific instance is being passed as an argument.
The equivalent lambda:
people.forEach(person -> System.out.println(person));
Also for transforming streams we can apply references to static methods:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
numbers.stream().map(String::valueOf)
This example passes a reference to the static valueOf()
method on the String
type. Therefore, the instance object in the collection is passed as an argument to valueOf()
.
The equivalent lambda:
numbers.stream().map(num -> String.valueOf(num))
List<String> strings = Arrays.asList("1", "2", "3");
strings.stream().map(Integer::new)
Read Collect Elements of a Stream into a Collection to see how to collect elements to collection.
The single String argument constructor of the Integer
type is being used here, to construct an integer given the string provided as the argument. In this case, as long as the string represents a number, the stream will be mapped to Integers.
The equivalent lambda:
strings.stream().map(s -> new Integer(s));
Method Reference Format | Code | Equivalent Lambda |
---|---|---|
Static method | TypeName::method | (args) -> TypeName.method(args) |
Non-static method (on instance*) | instance::method | (args) -> instance.method(args) |
Non-static method (no instance) | TypeName::method | (instance, args) -> instance.method(args) |
Constructor** | TypeName::new | (args) -> new TypeName(args) |
Array constructor | TypeName[]::new | (int size) -> new TypeName[size] |
* instance
can be any expression that evaluates to a reference to an instance, e.g. getInstance()::method
, this::method
** If TypeName
is a non-static inner class, constructor reference is only valid within the scope of an outer class instance