With Java 8, streams revolutionized how we process data. Instead of writing verbose loops, we can write declarations that express what we want to achieve rather than how to do it. This collection lists standard cookbook recipes for common programming tasks.
In this guide, we will walk through partition grouping, frequency counting, merging arrays, and reversing lists using streams.
Recipe 1: Splitting Numbers into Odd and Even Lists
You can use Collectors.partitioningBy() to split an array or list into a Map with true and false boolean keys:
Integer[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Map<Boolean, List<Integer>> partitioned = Stream.of(numbers)
.collect(Collectors.partitioningBy(num -> num % 2 == 0));
System.out.println("Evens: " + partitioned.get(true)); // [2, 4, 6, 8, 10]
System.out.println("Odds: " + partitioned.get(false)); // [1, 3, 5, 7, 9]
Recipe 2: Finding Word and Character Frequency
To count how many times words or characters appear in a dataset, use Collectors.groupingBy() combined with Collectors.counting():
// Word Frequency
List<String> names = Arrays.asList("rohit", "urmila", "rohit", "ram", "sita");
Map<String, Long> counts = names.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(counts); // {rohit=2, sita=1, urmila=1, ram=1}
Recipe 3: Merging Two Arrays to a Sorted List without Duplicates
You can concatenate two streams using IntStream.concat(), box them, and apply sorting operations:
int[] firstArr = {11, 12, 1, 2, 3};
int[] secondArr = {10, 20, 1, 12};
List<Integer> merged = IntStream.concat(Arrays.stream(firstArr), Arrays.stream(secondArr))
.boxed()
.sorted()
.distinct()
.collect(Collectors.toList());
System.out.println(merged); // [1, 2, 3, 10, 11, 12, 20]
Recipe 4: Finding the Second Largest Element
You can quickly skip and limit elements on a sorted stream to find leaders or runner-up entries:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
list.stream()
.sorted(Comparator.reverseOrder()) // Sort largest first
.limit(2) // Take top 2
.skip(1) // Skip the first largest
.forEach(System.out::println); // Prints: 9
Recipe 5: Generating the Fibonacci Series
Using Stream.iterate(), you can generate math sequences on the fly using seeds:
Stream.iterate(new int[]{0, 1}, t -> new int[]{t[1], t[0] + t[1]})
.limit(10)
.map(t -> t[0])
.forEach(System.out::println); // Prints first 10 Fibonacci numbers
Conclusion
Java 8 Streams abstract away mechanical iteration. Chaining operations like filter, map, distinct, and collector mapping turns complex data sorting problems into clean, readable code.