Built-in Functional Interfaces

A functional interface is an interface with exactly one abstract method, and Java's java.util.function package provides ready-made ones — Function , Predicate , Consumer , Supplier and more — that your lambdas and method references plug into.

Learn Built-in Functional Interfaces in our free Java course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…

Part of the free Java course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

You should know lambdas and method references , plus basic generics like Function<T, R> . Available since Java 8 .

💡 Analogy: Think of these interfaces as standard plug shapes for behaviour. A Supplier is a vending machine — press it, get something out, no input needed. A Consumer is a shredder — feed something in, nothing comes back. A Predicate is a metal detector — pass something through, get a yes/no. A Function is a juicer — fruit in, juice out. Once you know the shape, any lambda of that shape just clicks in.

Because these shapes are standard, the whole Stream API and countless libraries speak the same language — you write a lambda and it fits everywhere the matching interface is expected.

Memorise these by their one method: Function<T,R>.apply (T → R), Predicate<T>.test (T → boolean), Consumer<T>.accept (T → void), and Supplier<T>.get (void → T).

BiFunction<T,U,R> takes two inputs. When a Function's input and output are the same type, the specialised UnaryOperator<T> (one arg) and BinaryOperator<T> (two args) read more clearly than spelling out Function<T,T> .

The real power is building bigger behaviour from small pieces. Function has andThen (this, then next) and compose (next, then this). Predicate has and , or , and negate . Each returns a brand-new function, so you can chain freely.

When none of the built-ins fits — for example you want a descriptive name — declare your own interface with a single abstract method and mark it @FunctionalInterface . The annotation makes the compiler enforce the one-method rule, while you can still add default and static helper methods.

Predict the result before opening each answer.

Answer: Supplier<String> . It takes no input and returns a value, which is exactly get() .

Answer: 30 . andThen runs f first (2+1=3), then g (3*10=30).

Answer: No. @FunctionalInterface requires exactly one abstract method, but this has two. error: Two is not a functional interface . Remove one or make it default .

🎯 Your Turn — A length-range Predicate

Combine two Predicate<String> s with .and() to accept only 3–8 character strings.

🧩 Mini-Challenge — A text pipeline

Chain three steps with andThen , mixing method references and a lambda.

You now know the core functional interfaces and how to choose one by its inputs and outputs, how to compose Function s with andThen / compose , how to combine Predicate s with and / or / negate , and how to write your own @FunctionalInterface .

Next up: Checkpoint: Modern Java — pull every feature in this unit together in one build challenge.

Practice quiz

What is a functional interface?

  • An interface with many methods
  • A class with no fields
  • An interface with exactly one abstract method
  • An enum

Answer: An interface with exactly one abstract method. A functional interface has exactly one abstract method, so a lambda or method reference can implement it.

Which interface takes a T and returns an R?

  • Function<T,R>
  • Predicate<T>
  • Consumer<T>
  • Supplier<T>

Answer: Function<T,R>. Function<T,R> maps an input of type T to an output of type R via apply.

Which interface takes a T and returns a boolean?

  • Function<T,Boolean>
  • Supplier<Boolean>
  • Consumer<T>
  • Predicate<T>

Answer: Predicate<T>. Predicate<T> tests a value and returns boolean via test.

Which interface takes nothing and returns a value?

  • Consumer<T>
  • Supplier<T>
  • Runnable
  • Predicate<T>

Answer: Supplier<T>. Supplier<T> produces a value with get() and takes no input.

Which interface takes a value and returns nothing?

  • Consumer<T>
  • Supplier<T>
  • Function<T,Void>
  • Predicate<T>

Answer: Consumer<T>. Consumer<T> performs a side effect via accept and returns nothing.

What is UnaryOperator<T>?

  • A Predicate
  • A two-argument function
  • A Function whose input and output are the same type T
  • A Supplier

Answer: A Function whose input and output are the same type T. UnaryOperator<T> extends Function<T,T> — same input and output type.

What does Function's andThen do?

  • Runs the other function first
  • Runs this function, then feeds its result to the next
  • Negates the function
  • Combines two predicates

Answer: Runs this function, then feeds its result to the next. f.andThen(g) computes g(f(x)) — this first, then the next.

What does Function's compose do?

  • Runs this function first
  • Same as andThen
  • Returns a Predicate
  • Runs the argument function first, then this one

Answer: Runs the argument function first, then this one. f.compose(g) computes f(g(x)) — the argument runs first.

Which Predicate methods combine or invert tests?

  • plus, minus
  • and, or, negate
  • map, filter
  • get, set

Answer: and, or, negate. Predicate offers and(), or(), and negate() to build compound conditions.

What does @FunctionalInterface do?

  • Makes an interface faster
  • Generates getters
  • Compile-time check that the interface has exactly one abstract method
  • Marks it deprecated

Answer: Compile-time check that the interface has exactly one abstract method. The annotation makes the compiler verify the single-abstract-method rule; default/static methods are still allowed.