Skip to content

FUNCTIONAL PROGRAMMING

Lambda & Functional Interfaces

Interface Method Use Case
Function<T, R> R apply(T t) Transform an input into an output
Predicate<T> boolean test(T t) Boolean-valued condition, e.g. filtering
Consumer<T> void accept(T t) Perform an action, no return value
Supplier<T> T get() Provide/produce a value, no input
BiFunction<T, U, R> R apply(T t, U u) Transform two inputs into an output
UnaryOperator<T> T apply(T t) Function<T, T> specialisation

Method References

Form Example Equivalent Lambda
Static method Integer::parseInt s -> Integer.parseInt(s)
Instance method (particular object) list::add x -> list.add(x)
Instance method (arbitrary object of a type) String::toUpperCase s -> s.toUpperCase()
Constructor ArrayList::new () -> new ArrayList<>()

Streams Basics

List<String> names = List.of("Bilbo", "Frodo", "Gandalf", "Aragorn");

List<String> longNames = names.stream()
    .filter(n -> n.length() > 5)
    .map(String::toUpperCase)
    .sorted()
    .toList(); // Java 16+ terminal shortcut for Collectors.toList()

Exam tip: Streams are lazily evaluated — intermediate operations (filter, map) only execute once a terminal operation (collect, toList, forEach, reduce) is invoked.