Skip to content

Lab: filling and filtering the catalog

☕ Java 17 · Passing Methods Around by Name · 3/3

Goal: use three method reference shapes in one small program, and see the one case where a lambda has to stay.

Setup: create CatalogDemo.java. All types are nested inside it. Run it with java CatalogDemo.java.

Step 1 — The types

import java.util.ArrayList;

public class CatalogDemo {

    record Movie(String title, boolean kidsFriendly) { }

    interface MovieFactory {
        Movie make(String t, boolean k);
    }

    interface MovieFilter {
        boolean keep(Movie m);
    }
}

The record gives a two-value constructor and a kidsFriendly() accessor. MovieFactory takes a String and a boolean and returns a Movie: exactly the constructor's shape.

Step 2 — Fill the catalog with a constructor reference

Inside CatalogDemo:

    public static void main(String[] args) {
        var catalog = new ArrayList<Movie>();

        MovieFactory factory = Movie::new;           // shape 4
        catalog.add(factory.make("Coco", true));
        catalog.add(factory.make("Narcos", false));

        System.out.println("Full catalog");
        catalog.forEach(System.out::println);         // shape 2
    }

Movie::new matches make(String, boolean) to the record's constructor. System.out::println calls println on one particular object, System.out, for each movie.

Full catalog
Movie[title=Coco, kidsFriendly=true]
Movie[title=Narcos, kidsFriendly=false]

Step 3 — Filter with an accessor reference

At the end of main:

        MovieFilter family = Movie::kidsFriendly;     // shape 3
        catalog.removeIf(m -> !family.keep(m));

kidsFriendly() takes no argument, yet keep() takes a Movie: the Movie passed to keep() becomes the object kidsFriendly() runs on.

removeIf removes the elements for which its condition is true. We want to remove the movies that are not kid-friendly, so the answer must be negated with !. A method reference can't add !: this one stays a lambda.

Step 4 — Print the result

        System.out.println("Family catalog:");
        catalog.forEach(System.out::println);         // shape 2
$ java CatalogDemo.java
Full catalog
Movie[title=Coco, kidsFriendly=true]
Movie[title=Narcos, kidsFriendly=false]
Family catalog:
Movie[title=Coco, kidsFriendly=true]

Narcos is gone. A constructor reference built the movies, an accessor reference decided what's family-friendly, a lambda with ! removed the rest, and println printed what survived.

Full code on GitHub

← Parameter and constructor shapes · Back to the series


🎓 Preparing the OCP Java 17 exam? Exam traps and practice questions for this section → (optional)