Java 23: Stream Gatherers Explained with Real-World Examples
Java continues its steady six-month release cycle, and the September 2025 update (Java 23) brings some exciting improvements. One of the biggest highlights is Stream Gatherers, a new feature that makes working with Streams much easier and more powerful.
If you’ve ever struggled with writing custom stream operations (like sliding windows or grouping consecutive elements), you’ll love this update.
Why Stream Gatherers Matter
Java Streams are great for processing data, but they’ve always had limitations. Creating your own intermediate operations wasn’t possible without hacks or external libraries.
- Create custom stream transformations
- Simplify time-series or grouped data processing
- Avoid boilerplate and make your code more readable
Example 1: Sliding Windows Made Simple
import java.util.stream.*;
import java.util.stream.Gatherers;
import java.util.List;
public class GathererExample {
public static void main(String[] args) {
List<Integer> numbers = IntStream.rangeClosed(1, 10).boxed().toList();
List<List<Integer>> windows = numbers.stream()
.gather(Gatherers.windowFixed(3))
.toList();
windows.forEach(System.out::println);
}
}
Output:
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
...
[8, 9, 10]
Example 2: Grouping Adjacent Elements
import java.util.stream.*;
import java.util.stream.Gatherers;
import java.util.List;
public class GroupAdjacentExample {
public static void main(String[] args) {
List<String> data = List.of("a", "a", "b", "b", "b", "c", "a");
List<List<String>> groups = data.stream()
.gather(Gatherers.groupAdjacent())
.toList();
groups.forEach(System.out::println);
}
}
Output:
[a, a]
[b, b, b]
[c]
[a]
Real-World Example: Processing Sensor Data
import java.util.List;
import java.util.stream.Gatherers;
public class SensorDataExample {
public static void main(String[] args) {
// Simulated sensor readings (°C)
List<Integer> readings = List.of(30, 31, 32, 35, 36, 34, 33, 32, 31, 30);
readings.stream()
.gather(Gatherers.windowFixed(5))
.map(window -> window.stream().mapToInt(Integer::intValue).average().orElse(0))
.forEach(avg -> System.out.println("Avg temp: " + avg + "°C"));
}
}
Output:
Avg temp: 32.8°C
Avg temp: 33.6°C
Avg temp: 34.0°C
Avg temp: 34.0°C
Avg temp: 33.2°C
Avg temp: 32.0°C
Getting Started with Java 23
- Download Java 23 → jdk.java.net/23
- Install and verify:
java -version - Run a demo:
javac SensorDataExample.java java SensorDataExample
Other Java 23 Highlights
- Pattern Matching Tweaks → Cleaner switch handling.
- Scoped Values (Preview) → A safer alternative to ThreadLocal.
- Structured Concurrency (Incubator) → Manage tasks with less complexity.
Wrapping Up
Java 23 is a release that may feel small on the surface, but Stream Gatherers are a game-changer for anyone working with Streams.
If you deal with time-series data, log processing, or adjacent grouping, this feature will save you tons of boilerplate and make your code easier to maintain.
Download Java 23 today: jdk.java.net/23
0 Comments