100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Java Mastery
35 minintermediate

Method References and Composing Functions

Lambdas let you write small functions inline, but very often the function you want already exists as a named method, and writing a lambda that does nothing but call it is noise. Method references are a compact syntax, ClassName::methodName, that points directly at an existing method to be used wherever a functional interface is expected, so list.forEach(System.out::println) replaces list.forEach(x -> System.out.println(x)) with no loss of meaning and a clear gain in readability.

Alongside references, the functional interfaces in java.util.function, Function, Predicate, Consumer, and the rest, expose default methods for composition: you can glue small functions together into larger ones with andThen, compose, and, or, and negate, building behaviour from reusable pieces rather than one monolithic lambda. Composition turns functions into building blocks that snap together.

Understanding method references and composition matters because they are what make functional Java concise and expressive rather than merely possible. They let you name intent (Player::score reads as 'the score of a player'), reuse logic across many call sites, and assemble pipelines declaratively, which is exactly the style the Streams API rewards and which dominates modern Java codebases.

Analogy🏏Cricket
🏏 Think of it like cricket: a team sheet does not just list players, it assigns each to a precise, declared role, opener, spinner, wicketkeeper, and the laws and the captain enforce that a player operates within their declared role: you cannot send a designated bowler to keep wicket without an official change. Just as each player's role is fixed and checked before play, each Java variable's type is fixed at compile time and checked by the compiler. Just as trying to use a player outside their role is caught by the officials before it disrupts the match, using a variable in a type-incompatible way is caught by the compiler before the program runs. Just as clear role assignments prevent on-field confusion, clear type declarations prevent runtime errors. The insight is that declaring and enforcing roles up front, for players or for data, catches mistakes early rather than mid-match.
Lesson 19 of 35
0% complete