Master Java Stream API: From Basics to Advanced Operations
This article introduces Java 8's Stream API, explains why functional streams improve code readability and performance, and walks through core operations such as filter, map, flatMap, reduce, collect, Optional handling, concurrency, and debugging techniques with clear examples and illustrations.
Stream Introduction
Java 8 introduced a new Stream API. Unlike I/O streams, it behaves like an Iterable collection but with distinct characteristics.
Streams enhance collection functionality, focusing on convenient and efficient aggregation or bulk data operations.
By specifying operations—e.g., filtering strings longer than 10 characters or extracting first letters—Stream implicitly traverses elements and performs the transformations.
Why Use Streams
Functional programming makes code express business intent rather than implementation details, resulting in more readable, maintainable, reliable, and less error‑prone code.
Example Data Source
Filter
Used to traverse data and test each element. The filter method accepts a lambda expression as its predicate.
Map
Map creates a one‑to‑one transformation of each element, a commonly used operation that is simple to apply.
FlatMap
FlatMap is similar to map but supports deeper, one‑to‑many transformations, allowing each input element to be mapped to multiple output elements.
Method signatures:
<r> Stream<r> map(Function<? super T, ? extends R> mapper); <r> Stream<r> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);FlatMap handles scenarios where the mapping results in a collection of collections, flattening them into a single stream.
Reduce
Reduce performs aggregation similar to recursion, such as summing numbers or concatenating strings.
Collect
Collect creates common data structures from a stream, such as lists, sets, or maps, and also supports custom collectors.
Typical collectors include toList(), toSet(), and toMap().
Optional
Optional is a new data type designed to replace null, addressing many complaints about null handling. It is widely usable, including in lambda expressions.
Key methods: Optional.of(T) – creates an Optional for a non‑null value, otherwise throws an exception. Optional.ofNullable(T) – creates an Optional that may contain null. isPresent() – checks if a value is present (equivalent to != null). ifPresent(Consumer<? super T>) – executes the given lambda if the value is non‑null.
Concurrency
Replace stream() with parallelStream() or parallel() to enable parallel processing.
Performance depends on data size, source structure, boxing, CPU core count, and per‑element processing time.
Debugging
Streams are chained (e.g., list.stream().filter(...).map(...).collect(...)), with intermediate operations being lazy and terminal operations triggering evaluation.
Use peek() to inspect elements without terminating the stream.
Original source: https://www.jianshu.com/p/9fe8632d0bc2
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.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
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.
