๐ŸŽ“ A1Learner
๐Ÿ”
0 of 40 lessons completed

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?