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.
With Java 23’s Stream Gatherers, you can now:
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]
👉 In just one line, you get sliding windows without writing nested loops.
---
🧩 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]
This is great for text processing, logs, or sequences where grouping by adjacency matters.
---
🌍 Real-World Example: Processing Sensor Data
Imagine you’re working on an IoT system where temperature readings come in every second. Instead of raw values, you want to analyze sliding averages over 5 seconds.
import java.util.List;
import java.util.stream.IntStream;
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
👉 This makes data analysis cleaner and less noisy, perfect for monitoring dashboards.
---
⚡ Getting Started with Java 23
1. Download Java 23 → jdk.java.net/23
2. Install and verify:
java -version
3. Run a demo:
javac SensorDataExample.java
java SensorDataExample
No external dependencies are required — gatherers are built into the standard library.
---
🎯 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