Java 8
Lambdas
Function.identity()
Programming
Coding Practices

Java 8 lambdas, Function.identity() or t->t

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

In Java, Function.identity() and the lambda t -> t mean the same thing when the target type is Function<T, T>. The real question is not correctness, but readability: when does the named identity function express intent better than an inline lambda.

They Are Semantically Equivalent

Both forms return the input unchanged.

java
1import java.util.function.Function;
2
3public class IdentityDemo {
4    public static void main(String[] args) {
5        Function<String, String> a = Function.identity();
6        Function<String, String> b = t -> t;
7
8        System.out.println(a.apply("hello"));
9        System.out.println(b.apply("hello"));
10    }
11}

Both print the same result because both are identity functions.

Where Function.identity() Reads Better

The named method is especially clear in stream collector code because it says exactly what is happening without inventing a parameter name.

java
1import java.util.List;
2import java.util.Map;
3import java.util.function.Function;
4import java.util.stream.Collectors;
5
6public class ToMapDemo {
7    public static void main(String[] args) {
8        List<String> names = List.of("ava", "ben", "cara");
9
10        Map<String, String> map = names.stream()
11                .collect(Collectors.toMap(Function.identity(), String::toUpperCase));
12
13        System.out.println(map);
14    }
15}

In code like Collectors.toMap(Function.identity(), ...), the intent is obvious: use the stream element itself as the map key.

Where t -> t Can Be Fine

An inline lambda is completely acceptable when it is short, local, and does not obscure the expression around it.

java
1import java.util.function.Function;
2
3public class LambdaDemo {
4    public static void main(String[] args) {
5        Function<Integer, Integer> same = t -> t;
6        System.out.println(same.apply(42));
7    }
8}

This is not wrong or slower in any way that matters for normal code.

Why Many Developers Prefer Function.identity()

There are a few practical reasons:

  • it is explicit about intent
  • it avoids meaningless parameter names such as t
  • it is common in collector code, so many Java developers recognize it immediately

In that sense, Function.identity() is often more communicative than the lambda.

Type Inference and Target Type

Both forms still depend on context. Function.identity() returns a Function<T, T>, so it only makes sense when the input and output types are the same.

If your mapping is not truly identity, use a lambda or method reference that says what is actually happening.

java
1import java.util.List;
2import java.util.Map;
3import java.util.stream.Collectors;
4
5public class Example {
6    public static void main(String[] args) {
7        List<String> names = List.of("ava", "ben");
8
9        Map<String, Integer> lengths = names.stream()
10                .collect(Collectors.toMap(name -> name, String::length));
11
12        System.out.println(lengths);
13    }
14}

Here Function.identity() would also work for the key mapper, but the explicit lambda is not unreasonable if you think it improves local clarity.

Style Guidance

A pragmatic rule works well:

  • use Function.identity() in stream and collector code where identity is the real intent
  • use t -> t when the lambda form is already more natural in surrounding code

Consistency inside the codebase matters more than dogma.

Method References Are a Different Question

Sometimes this discussion appears next to method references. But Function.identity() is not a method reference replacement. It is a factory for a specific Function implementation. The comparison is only between two ways to express the identity mapping.

Common Pitfalls

The biggest pitfall is arguing about the two forms as if one is fundamentally more correct. They are functionally equivalent in the normal Java 8 use cases.

Another issue is using Function.identity() where the function is not actually identity. If the code transforms the value in any way, the named helper becomes misleading.

Developers also write t -> t in dense collector expressions where the parameter name adds no value and the whole line becomes slightly harder to scan.

Finally, do not assume either form solves duplicate-key problems in Collectors.toMap. Identity key mapping is orthogonal to merge-function concerns.

Summary

  • 'Function.identity() and t -> t are equivalent identity mappings in Java.'
  • 'Function.identity() often reads better in streams and collectors.'
  • 't -> t is still perfectly valid and sometimes fine for local clarity.'
  • Use the form that makes intent obvious in the surrounding code.
  • Prefer consistency and readability over style arguments that do not change behavior.

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.