Java
Programming
Arrow Operator
Coding
Java Syntax

What does the arrow operator, '->', do in Java?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

The arrow operator (->) in Java separates the parameter list from the body in lambda expressions and switch expressions. Introduced in Java 8 for lambdas and extended to switch in Java 14, it is the core syntax that enables functional-style programming in Java.

Lambda Expressions: The Primary Use

A lambda expression is an anonymous function that implements a functional interface (an interface with exactly one abstract method). The arrow operator divides the input parameters (left side) from the implementation body (right side):

java
1// Syntax: (parameters) -> expression_or_block
2
3// No parameters
4Runnable task = () -> System.out.println("Running");
5
6// Single parameter (parentheses optional)
7Consumer<String> printer = s -> System.out.println(s);
8
9// Multiple parameters
10BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
11
12// Block body with return
13Comparator<String> byLength = (s1, s2) -> {
14    int diff = s1.length() - s2.length();
15    return diff;
16};

The Java compiler infers parameter types from the target functional interface, so you rarely need to specify them explicitly.

How Lambda Expressions Replace Anonymous Classes

Before Java 8, implementing a functional interface required an anonymous inner class. The arrow operator eliminates that boilerplate:

java
1// Before Java 8: anonymous inner class
2Collections.sort(names, new Comparator<String>() {
3    @Override
4    public int compare(String a, String b) {
5        return a.compareToIgnoreCase(b);
6    }
7});
8
9// Java 8+: lambda with arrow operator
10Collections.sort(names, (a, b) -> a.compareToIgnoreCase(b));
11
12// Even shorter with method reference
13Collections.sort(names, String::compareToIgnoreCase);

The anonymous class version requires 6 lines. The lambda version requires 1 line. The behavior is identical.

Using Lambdas with the Streams API

The arrow operator becomes especially powerful with the Streams API, where you chain operations on collections:

java
1List<String> names = List.of("Alice", "Bob", "Charlie", "Diana", "Eve");
2
3// Filter, transform, and collect in a pipeline
4List<String> result = names.stream()
5    .filter(name -> name.length() > 3)        // Predicate<String>
6    .map(name -> name.toUpperCase())           // Function<String, String>
7    .sorted((a, b) -> a.compareTo(b))          // Comparator<String>
8    .collect(Collectors.toList());
9// result: ["ALICE", "CHARLIE", "DIANA"]

Each arrow operator creates a lambda that the stream pipeline invokes for every element.

Common Functional Interfaces

Java's java.util.function package provides standard functional interfaces used with lambdas:

InterfaceMethod SignatureLambda Example
Predicate<T>boolean test(T t)x -> x > 10
Function<T, R>R apply(T t)s -> s.length()
Consumer<T>void accept(T t)s -> System.out.println(s)
Supplier<T>T get()() -> new ArrayList<>()
BiFunction<T, U, R>R apply(T t, U u)(a, b) -> a + b
UnaryOperator<T>T apply(T t)x -> x * 2
BinaryOperator<T>T apply(T t1, T t2)(a, b) -> Math.max(a, b)

You do not need to define your own functional interface unless none of these fit your use case.

Arrow Operator in Switch Expressions (Java 14+)

Java 14 introduced a second use of the arrow operator in switch expressions. Instead of the traditional case: ... break; pattern, you use case VALUE -> for concise, fall-through-free branches:

java
1// Traditional switch (prone to fall-through bugs)
2String result;
3switch (day) {
4    case MONDAY:
5    case FRIDAY:
6        result = "Work hard";
7        break;
8    case SATURDAY:
9    case SUNDAY:
10        result = "Relax";
11        break;
12    default:
13        result = "Normal day";
14        break;
15}
16
17// Switch expression with arrow operator (Java 14+)
18String result = switch (day) {
19    case MONDAY, FRIDAY -> "Work hard";
20    case SATURDAY, SUNDAY -> "Relax";
21    default -> "Normal day";
22};

The arrow form does not fall through to the next case, eliminating a whole class of bugs. If the branch needs multiple statements, use a block with yield:

java
1String result = switch (statusCode) {
2    case 200 -> "OK";
3    case 404 -> "Not Found";
4    case 500 -> {
5        logError(statusCode);
6        yield "Internal Server Error";
7    }
8    default -> "Unknown status";
9};

Variable Capture and Effectively Final

Lambdas can capture variables from the enclosing scope, but those variables must be effectively final (never reassigned after initialization):

java
1String prefix = "Hello, ";  // effectively final
2
3// This works - prefix is never reassigned
4Function<String, String> greeter = name -> prefix + name;
5
6// This would NOT compile:
7// prefix = "Hi, ";  // reassignment makes it non-effectively-final

This restriction exists because the lambda may execute later (or on a different thread), and allowing mutation would introduce race conditions.

Method References as Shorthand

When a lambda simply calls an existing method, you can replace it with a method reference using :::

java
1// Lambda with arrow operator
2names.forEach(name -> System.out.println(name));
3
4// Equivalent method reference (no arrow needed)
5names.forEach(System.out::println);
6
7// Static method reference
8numbers.stream().map(n -> String.valueOf(n));
9numbers.stream().map(String::valueOf);
10
11// Instance method reference
12names.stream().map(s -> s.toUpperCase());
13names.stream().map(String::toUpperCase);

Method references are not a replacement for the arrow operator. They are syntactic sugar for the specific case where the lambda body is a single method call that forwards all parameters directly.

Common Pitfalls

Returning a value from a void-context lambda. If the functional interface method returns void, using an expression body that has a return value is allowed but can be confusing. Be explicit with a block body if the intent is unclear.

Forgetting that block-body lambdas need explicit return. An expression body (x -> x + 1) implicitly returns the result. A block body (x -> { x + 1; }) does not. You must write x -> { return x + 1; } for the block form.

Confusing the arrow operator with method references. The -> and :: syntax serve different purposes. Use -> when you need custom logic. Use :: only when the lambda body is a direct method delegation.

Overusing lambdas in deeply nested chains. While stream().filter().map().flatMap().collect() is powerful, chains longer than 3-4 operations become hard to read. Extract complex lambdas into named methods and use method references instead.

Shadowing outer variables. Lambda parameters cannot have the same name as a variable in the enclosing scope. This causes a compilation error, unlike anonymous classes which create a new scope.

java
String name = "outer";
// Compilation error: variable 'name' is already defined
Consumer<String> c = name -> System.out.println(name);

Summary

The arrow operator (->) is Java's syntax for separating inputs from logic in two contexts: lambda expressions (Java 8+) and switch expressions (Java 14+). In lambdas, it enables functional-style programming by providing concise anonymous function syntax that works with the Streams API and functional interfaces. In switch expressions, it eliminates fall-through bugs and enables switch to return values directly. Understanding the arrow operator is essential for writing modern Java code, as nearly all collection processing, event handling, and concurrent programming patterns in current Java rely on it.


Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.