Skip to content

Intermediate · Lambdas, streams and files · topic 37 of 60 · 20 min

Method references

Explanation

A method reference is a shorter lambda that just calls an existing method: String::length instead of s -> s.length(). There are four kinds: static (Integer::parseInt), on a particular object (System.out::println), on an arbitrary object of a type (String::toUpperCase), and constructors (ArrayList::new). Use them when they make code clearer.

From lambda to method reference

Many lambdas do nothing but call one method with the same arguments. Java lets you name that method directly with ClassName::methodName or object::methodName. The compiler matches it to the functional interface expected, exactly as for a lambda.

java
List<String> names = List.of("asha", "ravi", "meena");

names.forEach(n -> System.out.println(n));
names.forEach(System.out::println);                         // same thing

List<Integer> lengths = names.stream().map(s -> s.length()).toList();
List<Integer> lengths2 = names.stream().map(String::length).toList();   // same thing

The four kinds

KindSyntaxEquivalent lambda
Static methodInteger::parseInts -> Integer.parseInt(s)
Instance method of a particular objectSystem.out::printlnx -> System.out.println(x)
Instance method of an arbitrary object of a typeString::toUpperCases -> s.toUpperCase()
ConstructorArrayList::new() -> new ArrayList<>()
java
List<Integer> qtys = Stream.of("3", "10", "7").map(Integer::parseInt).toList();   // static
List<String> upper = names.stream().map(String::toUpperCase).toList();           // arbitrary object
Supplier<List<String>> newList = ArrayList::new;                                   // constructor
Function<String, StringBuilder> toBuilder = StringBuilder::new;                    // constructor with an argument

GstCalculator calc = new GstCalculator(18);
List<Double> withTax = List.of(100.0, 250.0).stream().map(calc::apply).toList(); // particular object

The "arbitrary object" kind, explained

String::compareToIgnoreCase used as a Comparator<String> means (a, b) -> a.compareToIgnoreCase(b): the FIRST argument becomes the object the method is called on, and the rest become its arguments. This is how Comparator.comparing(Employee::name) works: Employee::name means e -> e.name().

java
List<String> cities = new ArrayList<>(List.of("pune", "Agra", "delhi"));
cities.sort(String::compareToIgnoreCase);   // [Agra, delhi, pune]

Method references in everyday code

You will meet method references constantly in real projects: list.forEach(System.out::println) for quick output, map(String::strip) and filter(Predicate.not(String::isBlank)) for cleaning input, Comparator.comparing(Order::createdAt) for sorting, map(OrderDto::from) to convert entities to response objects in a Spring Boot service, and collect(Collectors.toMap(Product::sku, Function.identity())) to index a list by a key. Reading them fluently is as important as writing them.

java
Map<String, Product> bySku = products.stream()
        .collect(Collectors.toMap(Product::sku, Function.identity()));   // identity: the element itself
List<OrderDto> dtos = orders.stream().map(OrderDto::from).toList();      // a static factory method
Careful: A method reference can be ambiguous when a class has overloaded methods that both fit, and then the code does not compile; fall back to an explicit lambda. Also, do not force method references everywhere: x -> x * 2 is clearer than writing a helper method just to use ::.
Think of it like this: A lambda is like writing out a full instruction ("take the parcel, read the weight, write it down"). A method reference is like pointing at a poster on the wall that already has those instructions and saying "do that". Same result, fewer words, when the poster exists.
Tip: IDEs such as IntelliJ IDEA suggest "replace lambda with method reference" automatically. Accept the suggestion when the result reads well.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Method references · 1/6

Method references

In this lesson you will shorten lambdas with method references.

Prefer a video by a teacher? Find free videos on “java method references four types explained” on YouTube ↗

In real life: Cleaning imported phone numbers

An SMS campaign tool imports phone numbers from a spreadsheet. Each step of cleaning is an existing method, so the pipeline is a readable list of method references.

java
List<String> raw = List.of(" 98765 43210", "+91-9123456789", "  ");
List<String> clean = raw.stream()
        .map(String::strip)
        .filter(Predicate.not(String::isBlank))     // Java 11+
        .map(PhoneUtil::normalise)                  // your own static method
        .toList();

Practice (0/3 done)

Task 1 · Question

Which lambda is equivalent to String::trim used as a Function<String, String>?

Task 2 · Question

Which method reference fits Supplier<List<String>>?

Task 3 · Practice

Rewrite these lambdas as method references, and say which kind each is: (1) s -> Integer.parseInt(s) (2) x -> System.out.println(x) (3) s -> s.toLowerCase() (4) () -> new HashMap<String, Integer>() (5) (a, b) -> a.compareTo(b) for Strings.

Quick quiz

Question 1

1.What kind is System.out::println?

Question 2

2.Employee::name used in Comparator.comparing means…

Question 3

3.Which is a constructor reference?

Question 4

4.When should you prefer an explicit lambda over a method reference?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What kind is System.out::println?

Answer: Instance method of a particular object

System.out is a specific PrintStream object.

Employee::name used in Comparator.comparing means…

Answer: e -> e.name()

It is the arbitrary-object kind.

Which is a constructor reference?

Answer: StringBuilder::new

ClassName::new.

When should you prefer an explicit lambda over a method reference?

Answer: When the reference would be ambiguous or less clear

Readability decides.

"a.b.c".split(".") returns an array of length…Related

Answer: 0

split takes a regex; "." matches every character, and trailing empty strings are removed, leaving an empty array. Use split("\\.").

From Strings in depth

When did lambdas arrive in Java?Related

Answer: Java 8

Java 8 (2014) added lambdas and streams.

From Lambdas and functional interfaces

What does this refer to inside a method?Related

Answer: The current object

this is the object the method was called on.

From Classes, objects and constructors

What is wrong with: const std::string& name() { std::string s = "Asha"; return s; }Related

Answer: It returns a reference to a local that is destroyed: a dangling reference

s dies when the function returns. Return std::string by value.

From References: another name for a variable

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 3 more topics in “Lambdas, streams and files” before its exam: Streams: filter, map and collect, Collectors: grouping and summarising, Reading and writing files.
  2. Module 8 exam: Lambdas, streams and files · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Multithreading and concurrency. 60 topics left in the course before the final exam.

← Previous: Lambdas and functional interfaces