Java 8 Lambda Expressions and Functional Interfaces: Syntax, Usage, and Examples

This article provides a comprehensive tutorial on Java 8 lambda syntax, functional interfaces, type checking, inference, variable capture, method references, and common functional interfaces such as Predicate, Consumer, Function, Supplier, and their practical code examples.

Full-Stack Internet Architecture
Full-Stack Internet Architecture
Full-Stack Internet Architecture
Java 8 Lambda Expressions and Functional Interfaces: Syntax, Usage, and Examples

The article begins with a brief note that it is a reading note of the book "Java 8 in Practice" and introduces the two lambda expression syntaxes: (parameters) -> expression and (parameters) -> { statements; }, explaining each part of the syntax.

It then presents five test cases to illustrate which lambda forms are valid, providing equivalent anonymous class implementations for each case, and explains why cases (4) and (5) are incorrect according to the lambda specification.

Next, the concept of functional interfaces is introduced: an interface with a single abstract method can be annotated with @FunctionalInterface and used as a target type for lambda expressions. An example shows assigning a lambda to a Runnable variable and passing it to a method.

The article demonstrates behavior parameterization by defining a custom functional interface BufferedReaderProcessor (with a method String process(BufferedReader b) throws IOException) and refactoring a file‑processing method to accept this interface, allowing different lambda expressions to dictate how the file is read.

Common functional interfaces from java.util.function are then described with code examples:

Predicate :

public static <T> List<T> filter(List<T> list, Predicate<T> p) { ... }

and usage Predicate<String> nonEmpty = s -> !s.isEmpty(); Consumer :

public static <T> void forEach(List<T> list, Consumer<T> c) { ... }

and usage forEach(Arrays.asList(1,2,3), i -> System.out.println(i)); Function :

public static <T,R> List<R> map(List<T> list, Function<T,R> f) { ... }

and usage

List<Integer> lengths = map(Arrays.asList("a","bb"), s -> s.length());

Supplier : Supplier<Apple> s = Apple::new; Apple a = s.get(); UnaryOperator , BiPredicate , BiConsumer , BiFunction , BinaryOperator : brief descriptions and example signatures are given.

The article also covers type checking and type inference for lambdas, showing how the compiler matches a lambda to the target functional interface and infers parameter types, with examples such as

Comparator<Apple> c = (a1,a2) -> a1.getWeight().compareTo(a2.getWeight());

.

Variable capture rules are explained: only effectively final local variables can be referenced inside a lambda, illustrated by a portNumber example.

Method references are introduced with three forms—static method reference, instance method reference, and constructor reference—accompanied by code snippets like Integer::parseInt, String::length, and Apple::new.

Finally, the article concludes that the basics of lambda syntax, functional interfaces, and method references have been covered, providing a solid foundation for using functional programming features in Java 8.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javaprogrammingLambdaFunctional Interfacejava8
Full-Stack Internet Architecture
Written by

Full-Stack Internet Architecture

Introducing full-stack Internet architecture technologies centered on Java

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.