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.
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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Full-Stack Internet Architecture
Introducing full-stack Internet architecture technologies centered on Java
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
