Java Lambda Expressions
A lambda expression writes a small method body without a name. It lets a rule travel as a value into a method call.
A helper class does a one-line job
The comparators lesson sorted students with a named helper class. The class holds one line of real work.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Ana", 92));
students.add(new Student("Ben", 75));
students.add(new Student("Cy", 88));
Collections.sort(students, new ByScore());
for (Student student : students) {
System.out.println(student.name + " " + student.score);
}
}
}
class ByScore implements Comparator<Student> {
public int compare(Student a, Student b) {
return Integer.compare(a.score, b.score);
}
}
class Student {
String name;
int score;
Student(String name, int score) {
this.name = name;
this.score = score;
}
}The same rule as a lambda
The lambda writes the compare rule inside the sort call. No helper class remains.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Ana", 92));
students.add(new Student("Ben", 75));
students.add(new Student("Cy", 88));
students.sort((a, b) -> Integer.compare(a.score, b.score));
for (Student student : students) {
System.out.println(student.name + " " + student.score);
}
}
}
class Student {
String name;
int score;
Student(String name, int score) {
this.name = name;
this.score = score;
}
}Three lambda forms
The forms differ in their parameters and their body. Each form below prints its result.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
Runnable starter = () -> System.out.println("Start");
starter.run();
List<String> names = List.of("Ana", "Ben");
names.forEach(name -> System.out.println(name));
List<Integer> scores = new ArrayList<>(List.of(70, 95, 82));
scores.sort((a, b) -> {
return Integer.compare(b, a);
});
System.out.println(scores);
}
}A lambda stored in a variable
A Comparator variable can hold a lambda. The sort call then uses the variable name.
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Cy", 88));
students.add(new Student("Ana", 92));
students.add(new Student("Ben", 75));
Comparator<Student> byName = (a, b) -> a.name.compareTo(b.name);
students.sort(byName);
for (Student student : students) {
System.out.println(student.name + " " + student.score);
}
}
}
class Student {
String name;
int score;
Student(String name, int score) {
this.name = name;
this.score = score;
}
}removeIf deletes by a lambda rule
removeIf keeps an element when the test answers false. Scores below 60 disappear from the list.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> scores = new ArrayList<>(List.of(45, 82, 61, 90, 38));
scores.removeIf(score -> score < 60);
System.out.println(scores);
}
}Example
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> words = new ArrayList<>(List.of("java", "go", "stream", "rust", "c"));
words.removeIf(word -> word.length() < 3);
words.sort((a, b) -> Integer.compare(a.length(), b.length()));
for (String word : words) {
System.out.println(word);
}
}
}Key points
- A lambda expression is a nameless block of code passed to a method.
- The arrow -> separates the parameters from the body.
- A lambda can stand only where a functional interface is expected.
- A lambda with no parameters writes empty parentheses before the arrow.
- A block body uses braces and writes return for its answer.
- removeIf tests each element with a lambda and deletes the matches.
In this example, removeIf deletes the words shorter than three letters. A lambda then sorts the surviving words by length. The printed words grow from four letters to six.
Note
A lambda does the job inline, so no separate helper class is needed for a one-use rule.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What does removeIf do with an element when its lambda answers true?