Using Java 8 Streams and Functional Interfaces: A Comprehensive Guide
This article explains Java 8's lambda expressions and functional interfaces, demonstrates common Stream operations such as filter, map, flatMap, collect, max/min, count and reduce, and shows how to use advanced collectors for grouping, partitioning and joining with clear code examples.
Java 8 introduced lambda expressions and functional interfaces, allowing developers to write concise functional‑style code. The article starts with an overview of lambda syntax and the purpose of functional interfaces like Predicate , Consumer , Function , Supplier , UnaryOperator and BinaryOperator .
Example code demonstrates creating a Predicate<Integer> to test a height condition, using a Consumer<String> to print messages, and defining a custom functional interface Worker with a test method.
public class Test {
public static void main(String[] args) {
Predicate
predicate = x -> x > 185;
Student student = new Student("9龙", 23, 175);
System.out.println("9龙的身高高于185吗?:" + predicate.test(student.getStature()));
Consumer
consumer = System.out::println;
consumer.accept("命运由我不由天");
Function
function = Student::getName;
String name = function.apply(student);
System.out.println(name);
Supplier
supplier = () -> Integer.valueOf(BigDecimal.TEN.toString());
System.out.println(supplier.get());
UnaryOperator
unaryOperator = uglily -> !uglily;
Boolean apply2 = unaryOperator.apply(true);
System.out.println(apply2);
BinaryOperator
operator = (x, y) -> x * y;
Integer integer = operator.apply(2, 3);
System.out.println(integer);
test(() -> "我是一个演示的函数式接口");
}
public static void test(Worker worker) {
String work = worker.work();
System.out.println(work);
}
public interface Worker {
String work();
}
}The article then moves to Stream API usage. It explains lazy evaluation versus eager evaluation and shows how to convert a Stream to a List with collect(Collectors.toList()) , filter elements, map objects to other types, and flatten nested streams.
// filter example
List
list = students.stream()
.filter(stu -> stu.getStature() < 180)
.collect(Collectors.toList());
// map example
List
names = students.stream()
.map(Student::getName)
.collect(Collectors.toList());
// flatMap example
List
studentList = Stream.of(students, asList(new Student("艾斯", 25, 183)))
.flatMap(List::stream)
.collect(Collectors.toList());Common terminal operations such as max , min , count and reduce are illustrated, highlighting the use of Optional to avoid null‑pointer errors.
// max/min example
Optional
max = students.stream()
.max(Comparator.comparing(Student::getAge));
Optional
min = students.stream()
.min(Comparator.comparing(Student::getAge));
// count example
long count = students.stream()
.filter(s -> s.getAge() < 45)
.count();
// reduce example
Integer sum = Stream.of(1, 2, 3, 4)
.reduce(0, (acc, x) -> acc + x);Advanced collectors are covered, including averagingInt for average calculations, partitioningBy for boolean splits, groupingBy for arbitrary grouping, and joining for concatenating strings with delimiters, prefixes and suffixes.
// groupingBy example
Map
> map = students.stream()
.collect(Collectors.groupingBy(s -> s.getSpecialities().get(0)));
// joining example
String names = students.stream()
.map(Student::getName)
.collect(Collectors.joining(",", "[", "]"));Finally, the article summarizes that Java 8 streams provide a clear, chainable way to process collections, encouraging readers to refactor existing code to take advantage of these functional features.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
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.