Introduction
Method references are more concise than lambdas. If method references are shorter and clearer, use them; otherwise, utilize lambdas. Method references reduce the boilerplate code and thus improves readability.
There are four kinds of method references, which are summarized below:
Kind | Example |
---|---|
Reference to a static method | ContainingClass::staticMethodName |
Reference to an instance method of a particular object | containingObject::instanceMethodName |
Reference to an instance method of an arbitrary object of a particular type | ContainingType::methodName |
Reference to a constructor | ClassName::new |
Static Method Reference
Suppose that you have a list of numbers and want return integers using Integer.parseInt()
List<String> numbers = Arrays.asList("1", "2", "3");
You can accomplish this by using lambda expression as follows
// lambda equivalent
numbers.forEach(name -> Integer.parseInt(name));
System.out.println("lambda equivalent: " + numbers);
Or, you can use the method reference. Integer::parseInt
is a reference to a static method.
// method reference
numbers.forEach(Integer::parseInt);
System.out.println("method reference: " + numbers);
Reference to an instance method of a particular object
Suppose that the members of your workout application are contained in an array, and you want to sort the array by duration. You could use the following code.
class WorkoutComparator implements Comparator<Workout> {
@Override
public int compare(Workout a, Workout b) {
return a.getDuration().compareTo(b.getDuration());
}
}
The following is an example of a reference to an instance method of a particular object.
Workout[] workoutArray =
{
new Workout(60, "chest&back"),
new Workout(50, "biceps&triceps"),
new Workout(70, "shoulders&legs")
};
WorkoutComparator myWorkoutComparator = new WorkoutComparator();
The method reference myWorkoutComparator::compare invokes the method compare that is part of the object myWorkoutComparator. The JRE infers the method type arguments, which in this case are (Workout, Workout)
Arrays.sort(workoutArray, myWorkoutComparator::compare);
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[] family = { "Suleyman", "Canan", "Fatma", "Omur", "Tomis" };
// method reference
Arrays.sort(family, String::compareTo);
// The equivalent lambda expression for the method reference
Arrays.sort(family, (a, b) -> a.compareTo(b));
Reference to a Constructor
Constructor references are similar to the method references. We just need to use the new operator. For instance, Workout::new is a reference to a Workout constructor.
Let’s create a list of Workout types.
List<String> workputTypes = Arrays.asList("chest", "back", "legs");
map() converts the stream of workout types to stream of Workout objects. Note that Workout::new equals to new Workout(“workout type”), such as new Workout(“chest“). The toArray accepts a constructor reference and creates an array of workout objects.
Workout[] workouts = workputTypes.stream()
.map(Workout::new)
.toArray(Workout[]::new);
for (Workout workout : workouts)
System.out.println(workout.getType() + " : "+ workout.getDuration());
Conclusion
In this item, we introduced four kinds of method references. If method references are shorter and clearer, use them; otherwise, utilize lambdas. The code is available on GitHub.