Method References
IntermediateReplace verbose lambdas with concise :: method references — four forms covering static, bound instance, unbound instance, and constructor references.
Overview
A method reference is shorthand for a lambda that does nothing but call an existing method. The :: operator names the method without calling it. There are four forms: static (Class::staticMethod), bound instance (obj::method), unbound instance (Class::method where first lambda arg is the receiver), and constructor (Class::new). They make stream pipelines more readable and eliminate boilerplate.
Four Forms of Method References
Static: Integer::parseInt → s -> Integer.parseInt(s) Bound instance: str::startsWith → s -> str.startsWith(s) Unbound instance: String::toLowerCase → s -> s.toLowerCase() Constructor: ArrayList::new → () -> new ArrayList<>()
import java.util.*;
import java.util.stream.*;
import java.util.function.*;
public class MethodRefForms {
static int doubleIt(int n) { return n * 2; }
public static void main(String[] args) {
// 1. Static method reference
Function<String, Integer> parser = Integer::parseInt;
System.out.println(parser.apply("42")); // 42
IntUnaryOperator dbl = MethodRefForms::doubleIt;
System.out.println(dbl.applyAsInt(5)); // 10
// 2. Bound instance — object is fixed
String prefix = "Hello";
Predicate<String> startsWithHello = prefix::startsWith; // fixed receiver
System.out.println(startsWithHello.test("Hello World")); // true
// 3. Unbound instance — object is first lambda arg
Function<String, String> upper = String::toUpperCase;
Comparator<String> cmp = String::compareTo;
System.out.println(upper.apply("java")); // JAVA
// 4. Constructor reference
Supplier<List<String>> listFactory = ArrayList::new;
Function<Integer, int[]> arrFactory = int[]::new;
List<String> list = listFactory.get();
int[] arr = arrFactory.apply(5);
System.out.println(arr.length); // 5
// Practical stream pipeline with method refs
List<String> nums = List.of("3", "1", "4", "1", "5");
List<Integer> sorted = nums.stream()
.map(Integer::parseInt) // static
.sorted(Integer::compareTo) // unbound
.collect(Collectors.toList());
System.out.println(sorted); // [1, 1, 3, 4, 5]
// Constructor ref in stream
List<StringBuilder> sbs = List.of("a","b","c").stream()
.map(StringBuilder::new) // constructor ref
.collect(Collectors.toList());
sbs.forEach(sb -> sb.append("!"));
System.out.println(sbs); // [a!, b!, c!]
}
}Method References in Practice
Method references shine in stream pipelines, Comparator chains, and event handlers. They are most readable when the method name clearly communicates intent. Prefer a lambda when the method reference would require mental indirection.
import java.util.*;
import java.util.stream.*;
public class MethodRefPractice {
record Person(String name, int age) {}
public static void main(String[] args) {
List<Person> people = List.of(
new Person("Charlie", 30),
new Person("Alice", 25),
new Person("Bob", 35));
// Comparator chains with method references
List<Person> sorted = people.stream()
.sorted(Comparator.comparingInt(Person::age)
.thenComparing(Person::name))
.collect(Collectors.toList());
sorted.forEach(p -> System.out.println(p.name() + ":" + p.age()));
// Printing with method reference
people.stream()
.map(Person::name)
.forEach(System.out::println); // bound instance on System.out
// Filtering with static method ref
List<String> strs = List.of("", "hello", "", "world");
long nonEmpty = strs.stream()
.filter(Predicate.not(String::isBlank)) // static method
.count();
System.out.println(nonEmpty); // 2
// Collecting names to uppercase
String result = people.stream()
.map(Person::name)
.map(String::toUpperCase)
.collect(Collectors.joining(", "));
System.out.println(result); // CHARLIE, ALICE, BOB → sorted earlier: ALICE, CHARLIE, BOB
}
}When to Use Lambda vs Method Reference
Use a method reference when: • The lambda does nothing but call one existing method • The method name is self-documenting
Use a lambda when: • The logic involves more than a single method call • You need to adapt parameters (e.g., swap order) • The method reference would be confusing
import java.util.*;
import java.util.stream.*;
import java.util.function.*;
public class LambdaVsRef {
public static void main(String[] args) {
List<String> words = List.of("banana","apple","cherry");
// PREFER method reference — single method call
words.stream().map(String::length).forEach(System.out::println);
// PREFER lambda — adapting parameter order
words.sort((a, b) -> b.compareTo(a)); // reverse — no clean method ref
// PREFER lambda — multiple operations
words.stream()
.filter(w -> w.length() > 4 && w.startsWith("b"))
.forEach(System.out::println);
// Predicate.not() wraps an instance method ref for negation
Predicate<String> notEmpty = Predicate.not(String::isEmpty); // Java 11+
System.out.println(words.stream().filter(notEmpty).count()); // 3
// BiFunction with unbound method ref
BiFunction<String, String, Boolean> contains = String::contains;
System.out.println(contains.apply("hello world", "world")); // true
}
}Interactive Visualization
stream.filter(n → n%2==0).map(n → n*n).sorted().collect(toList())Key Points to Remember
- Four forms: Class::staticMethod, instance::method, Class::instanceMethod, Class::new
- Unbound instance ref (String::toUpperCase) takes the receiver as the first lambda argument
- Constructor ref (ArrayList::new) is equivalent to () -> new ArrayList<>()
- System.out::println is a bound instance reference — System.out is the fixed receiver
- Prefer method references when the name communicates intent clearly; use lambdas for complex logic
- Predicate.not(method::ref) (Java 11+) negates a method reference cleanly
Practice Method References in the Playground
Run and modify code directly in your browser - no setup needed.
Interview Questions
Sign in to ask AriaWhat are the four types of method references in Java?
What is the difference between a bound and unbound instance method reference?
How does String::toUpperCase differ from s -> s.toUpperCase()?
When would you use a constructor reference?
Can a method reference throw a checked exception?
Ask Aria about Method References
Your personal AI tutor — ask anything about this concept