Card 06/ 09

ConceptDifficulty: Advanced1 min

Method References, and the Case Where You Cannot Use One

A lambda whose body does nothing but call one method, passing its parameters straight through, is repeating itself. A method reference names the method and lets the compiler do the rest.

The four forms of method reference, with the lambda each replaces
FormExampleThe lambda it replaces
A static methodInteger::parseInts -> Integer.parseInt(s)
A method on a particular objectSystem.out::printlns -> System.out.println(s)
A method on whichever object arrivesString::toUpperCases -> s.toUpperCase()
A constructorArrayList::new() -> new ArrayList<>()

The third row is the one that reads oddly at first. String::toUpperCase takes no argument in the source and produces a Function<String, String>: the parameter becomes the object the method is called on.

Where you cannot use one is where the body does anything other than pass its parameters straight through — reordering them, adding a constant, negating the result, or calling two things.

java
names.stream().map(String::toUpperCase)              // fine
names.stream().map(s -> s.toUpperCase().trim())      // two calls, so a lambda
names.stream().filter(s -> !s.isBlank())             // negated, so a lambda

Use a method reference when it fits and do not contort a lambda to make one fit. s -> !s.isBlank() is clearer than any arrangement that avoids it.