Stream Operations
Stream Collect
After filtering and transforming stream elements, you typically need to gather results into a collection or compute aggregate values. The collect operation provides flexible, efficient ways to accumulate stream results.
Basic Collectors
The collect operation is a terminal operation that uses a Collector to gather elements.
The Collectors utility class provides common collectors for lists, sets, and maps.
import java.util.*;
import java.util.stream.*;
public class Basic {
public static void main(String[] args) {
List<String> words = ;
List<String> list = words.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println("list: " + list);
Set<String> set = words.stream().collect(Collectors.toCollection(LinkedHashSet::new));
System.out.println("set: " + set);
List<String> items = Arrays.asList("a", "bb", "ccc");
Map<String, Integer> lengths = items.stream()
.collect(Collectors.toMap(s -> s, String::length, (a, b) -> a, LinkedHashMap::new));
System.out.println("lengths: " + lengths);
}
}
import java.util.*;
import java.util.stream.*;
public class Basic {
public static void main(String[] args) {
List<String> words = ;
List<String> list = words.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println("list: " + list);
Set<String> set = words.stream().collect(Collectors.toCollection(LinkedHashSet::new));
System.out.println("set: " + set);
List<String> items = Arrays.asList("a", "bb", "ccc");
Map<String, Integer> lengths = items.stream()
.collect(Collectors.toMap(s -> s, String::length, (a, b) -> a, LinkedHashMap::new));
System.out.println("lengths: " + lengths);
}
}
import java.util.*;
import java.util.stream.*;
public class Basic {
public static void main(String[] args) {
List<String> words = ;
List<String> list = words.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println("list: " + list);
Set<String> set = words.stream().collect(Collectors.toCollection(LinkedHashSet::new));
System.out.println("set: " + set);
List<String> items = Arrays.asList("a", "bb", "ccc");
Map<String, Integer> lengths = items.stream()
.collect(Collectors.toMap(s -> s, String::length, (a, b) -> a, LinkedHashMap::new));
System.out.println("lengths: " + lengths);
}
}
Joining Strings
The joining collector concatenates strings with optional delimiter, prefix, and suffix.
import java.util.*;
import java.util.stream.*;
public class Joining {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry");
String delimiter = ;
String concat = words.stream().collect(Collectors.joining());
System.out.println("concat: " + concat);
String csv = words.stream().collect(Collectors.joining(delimiter));
System.out.println("csv: " + csv);
String bracketed = words.stream()
.collect(Collectors.joining(", ", "[", "]"));
System.out.println("bracketed: " + bracketed);
List<Integer> nums = Arrays.asList(1, 2, 3);
String result = nums.stream()
.map(n -> "num" + n)
.collect(Collectors.joining(" | "));
System.out.println("result: " + result);
}
}
import java.util.*;
import java.util.stream.*;
public class Joining {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry");
String delimiter = ;
String concat = words.stream().collect(Collectors.joining());
System.out.println("concat: " + concat);
String csv = words.stream().collect(Collectors.joining(delimiter));
System.out.println("csv: " + csv);
String bracketed = words.stream()
.collect(Collectors.joining(", ", "[", "]"));
System.out.println("bracketed: " + bracketed);
List<Integer> nums = Arrays.asList(1, 2, 3);
String result = nums.stream()
.map(n -> "num" + n)
.collect(Collectors.joining(" | "));
System.out.println("result: " + result);
}
}
import java.util.*;
import java.util.stream.*;
public class Joining {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry");
String delimiter = ;
String concat = words.stream().collect(Collectors.joining());
System.out.println("concat: " + concat);
String csv = words.stream().collect(Collectors.joining(delimiter));
System.out.println("csv: " + csv);
String bracketed = words.stream()
.collect(Collectors.joining(", ", "[", "]"));
System.out.println("bracketed: " + bracketed);
List<Integer> nums = Arrays.asList(1, 2, 3);
String result = nums.stream()
.map(n -> "num" + n)
.collect(Collectors.joining(" | "));
System.out.println("result: " + result);
}
}
Grouping
Group elements by a classification function into a Map<K, List<T>>.
import java.util.*;
import java.util.stream.*;
public class Grouping {
public static void main(String[] args) {
List<String> words = ;
Map<Character, List<String>> byFirstLetter = words.stream()
.collect(Collectors.groupingBy(w -> w.charAt(0), TreeMap::new, Collectors.toList()));
System.out.println("byFirstLetter: " + byFirstLetter);
Map<Integer, List<String>> byLength = words.stream()
.collect(Collectors.groupingBy(String::length, TreeMap::new, Collectors.toList()));
System.out.println("byLength: " + byLength);
Map<Character, Long> counts = words.stream()
.collect(Collectors.groupingBy(w -> w.charAt(0), TreeMap::new, Collectors.counting()));
System.out.println("counts: " + counts);
Map<Character, Double> avgLengths = words.stream()
.collect(Collectors.groupingBy(
w -> w.charAt(0),
TreeMap::new,
Collectors.averagingInt(String::length)
));
System.out.println("avgLengths: " + avgLengths);
}
}
import java.util.*;
import java.util.stream.*;
public class Grouping {
public static void main(String[] args) {
List<String> words = ;
Map<Character, List<String>> byFirstLetter = words.stream()
.collect(Collectors.groupingBy(w -> w.charAt(0), TreeMap::new, Collectors.toList()));
System.out.println("byFirstLetter: " + byFirstLetter);
Map<Integer, List<String>> byLength = words.stream()
.collect(Collectors.groupingBy(String::length, TreeMap::new, Collectors.toList()));
System.out.println("byLength: " + byLength);
Map<Character, Long> counts = words.stream()
.collect(Collectors.groupingBy(w -> w.charAt(0), TreeMap::new, Collectors.counting()));
System.out.println("counts: " + counts);
Map<Character, Double> avgLengths = words.stream()
.collect(Collectors.groupingBy(
w -> w.charAt(0),
TreeMap::new,
Collectors.averagingInt(String::length)
));
System.out.println("avgLengths: " + avgLengths);
}
}
import java.util.*;
import java.util.stream.*;
public class Grouping {
public static void main(String[] args) {
List<String> words = ;
Map<Character, List<String>> byFirstLetter = words.stream()
.collect(Collectors.groupingBy(w -> w.charAt(0), TreeMap::new, Collectors.toList()));
System.out.println("byFirstLetter: " + byFirstLetter);
Map<Integer, List<String>> byLength = words.stream()
.collect(Collectors.groupingBy(String::length, TreeMap::new, Collectors.toList()));
System.out.println("byLength: " + byLength);
Map<Character, Long> counts = words.stream()
.collect(Collectors.groupingBy(w -> w.charAt(0), TreeMap::new, Collectors.counting()));
System.out.println("counts: " + counts);
Map<Character, Double> avgLengths = words.stream()
.collect(Collectors.groupingBy(
w -> w.charAt(0),
TreeMap::new,
Collectors.averagingInt(String::length)
));
System.out.println("avgLengths: " + avgLengths);
}
}
Partitioning
Partition elements into two groups based on a predicate: Map<Boolean, List<T>>.
import java.util.*;
import java.util.stream.*;
public class Partitioning {
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
int minWordLength = ;
Map<Boolean, List<Integer>> partitioned = nums.stream()
.collect(Collectors.partitioningBy(n -> n % 2 == 0));
System.out.println("evens: " + partitioned.get(true));
System.out.println("odds: " + partitioned.get(false));
List<String> words = Arrays.asList("a", "bb", "ccc", "d", "eeee");
Map<Boolean, List<String>> longWords = words.stream()
.collect(Collectors.partitioningBy(s -> s.length() >= minWordLength));
System.out.println("longWords: " + longWords);
Map<Boolean, Long> counts = nums.stream()
.collect(Collectors.partitioningBy(n -> n > 5, Collectors.counting()));
System.out.println("counts: " + counts);
}
}
import java.util.*;
import java.util.stream.*;
public class Partitioning {
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
int minWordLength = ;
Map<Boolean, List<Integer>> partitioned = nums.stream()
.collect(Collectors.partitioningBy(n -> n % 2 == 0));
System.out.println("evens: " + partitioned.get(true));
System.out.println("odds: " + partitioned.get(false));
List<String> words = Arrays.asList("a", "bb", "ccc", "d", "eeee");
Map<Boolean, List<String>> longWords = words.stream()
.collect(Collectors.partitioningBy(s -> s.length() >= minWordLength));
System.out.println("longWords: " + longWords);
Map<Boolean, Long> counts = nums.stream()
.collect(Collectors.partitioningBy(n -> n > 5, Collectors.counting()));
System.out.println("counts: " + counts);
}
}
import java.util.*;
import java.util.stream.*;
public class Partitioning {
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
int minWordLength = ;
Map<Boolean, List<Integer>> partitioned = nums.stream()
.collect(Collectors.partitioningBy(n -> n % 2 == 0));
System.out.println("evens: " + partitioned.get(true));
System.out.println("odds: " + partitioned.get(false));
List<String> words = Arrays.asList("a", "bb", "ccc", "d", "eeee");
Map<Boolean, List<String>> longWords = words.stream()
.collect(Collectors.partitioningBy(s -> s.length() >= minWordLength));
System.out.println("longWords: " + longWords);
Map<Boolean, Long> counts = nums.stream()
.collect(Collectors.partitioningBy(n -> n > 5, Collectors.counting()));
System.out.println("counts: " + counts);
}
}
Aggregations with Downstream Collectors
Combine grouping with downstream collectors for powerful aggregations.
import java.util.*;
import java.util.stream.*;
public class Aggregations {
public static void main(String[] args) {
List<Integer> nums = ;
long count = nums.stream().collect(Collectors.counting());
System.out.println("count: " + count);
int sum = nums.stream().collect(Collectors.summingInt(Integer::intValue));
System.out.println("sum: " + sum);
double avg = nums.stream().collect(Collectors.averagingDouble(Integer::doubleValue));
System.out.println("avg: " + avg);
IntSummaryStatistics stats = nums.stream().collect(Collectors.summarizingInt(Integer::intValue));
System.out.println("stats: count=" + stats.getCount() + ", sum=" + stats.getSum() +
", min=" + stats.getMin() + ", max=" + stats.getMax() + ", avg=" + stats.getAverage());
}
}
import java.util.*;
import java.util.stream.*;
public class Aggregations {
public static void main(String[] args) {
List<Integer> nums = ;
long count = nums.stream().collect(Collectors.counting());
System.out.println("count: " + count);
int sum = nums.stream().collect(Collectors.summingInt(Integer::intValue));
System.out.println("sum: " + sum);
double avg = nums.stream().collect(Collectors.averagingDouble(Integer::doubleValue));
System.out.println("avg: " + avg);
IntSummaryStatistics stats = nums.stream().collect(Collectors.summarizingInt(Integer::intValue));
System.out.println("stats: count=" + stats.getCount() + ", sum=" + stats.getSum() +
", min=" + stats.getMin() + ", max=" + stats.getMax() + ", avg=" + stats.getAverage());
}
}
import java.util.*;
import java.util.stream.*;
public class Aggregations {
public static void main(String[] args) {
List<Integer> nums = ;
long count = nums.stream().collect(Collectors.counting());
System.out.println("count: " + count);
int sum = nums.stream().collect(Collectors.summingInt(Integer::intValue));
System.out.println("sum: " + sum);
double avg = nums.stream().collect(Collectors.averagingDouble(Integer::doubleValue));
System.out.println("avg: " + avg);
IntSummaryStatistics stats = nums.stream().collect(Collectors.summarizingInt(Integer::intValue));
System.out.println("stats: count=" + stats.getCount() + ", sum=" + stats.getSum() +
", min=" + stats.getMin() + ", max=" + stats.getMax() + ", avg=" + stats.getAverage());
}
}
Exercise: Practical.java
Collect transaction data grouped by category with totals and counts