有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准 https://blog.zysicyj.top
Java 8 引入的 Stream API 提供了强大的聚合操作,可以方便地对集合进行操作,如过滤、映射、归约和收集等。下面将详细介绍如何使用 Java Stream 的聚合功能,并通过具体示例进行演示。
Stream 的基本聚合操作
1. filter
用于过滤流中的元素,保留符合条件的元素。
1 2 3 4 5
| List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David"); List<String> filteredNames = names.stream() .filter(name -> name.startsWith("A")) .collect(Collectors.toList()); System.out.println(filteredNames);
|
2. map
用于将流中的元素映射到另外一个元素,通常用于转换操作。
1 2 3 4 5
| List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David"); List<Integer> nameLengths = names.stream() .map(String::length) .collect(Collectors.toList()); System.out.println(nameLengths);
|
3. reduce
用于将流中的元素反复结合起来,得到一个值。常用于求和、乘积、连接字符串等操作。
1 2 3 4
| List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); int sum = numbers.stream() .reduce(0, Integer::sum); System.out.println(sum);
|
聚合操作的高级用法
1. 分组 groupingBy
将流中的元素按照某个分类函数进行分类,结果是一个 Map。
1 2 3 4 5
| List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Anna"); Map<Character, List<String>> groupedByFirstLetter = names.stream() .collect(Collectors.groupingBy(name -> name.charAt(0))); System.out.println(groupedByFirstLetter);
|
2. 分区 partitioningBy
将流中的元素按照给定的谓词进行分区,结果是一个包含两个列表的 Map,一个是满足谓词的元素,另一个是不满足谓词的元素。
1 2 3 4 5
| List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); Map<Boolean, List<Integer>> partitioned = numbers.stream() .collect(Collectors.partitioningBy(n -> n % 2 == 0)); System.out.println(partitioned);
|
3. 统计 summarizingInt
, summarizingDouble
, summarizingLong
对流中的元素进行统计,结果是一个包含统计信息的对象,例如数量、总和、最小值、平均值和最大值。
1 2 3 4 5
| List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); IntSummaryStatistics stats = numbers.stream() .collect(Collectors.summarizingInt(Integer::intValue)); System.out.println(stats);
|
4. 收集到集合 toList
, toSet
, toMap
将流中的元素收集到不同类型的集合中。
1 2 3 4 5 6 7 8 9
| List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Alice"); Set<String> nameSet = names.stream() .collect(Collectors.toSet()); System.out.println(nameSet);
Map<String, Integer> nameLengthMap = names.stream() .distinct() .collect(Collectors.toMap(name -> name, String::length)); System.out.println(nameLengthMap);
|
完整示例
以下是一个使用 Stream API 进行聚合操作的完整示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| import java.util.*; import java.util.stream.*;
public class StreamAggregationExample { public static void main(String[] args) { List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Anna");
List<String> filteredNames = names.stream() .filter(name -> name.startsWith("A")) .collect(Collectors.toList()); System.out.println("Filtered Names: " + filteredNames);
List<Integer> nameLengths = names.stream() .map(String::length) .collect(Collectors.toList()); System.out.println("Name Lengths: " + nameLengths);
int totalLength = names.stream() .map(String::length) .reduce(0, Integer::sum); System.out.println("Total Length of All Names: " + totalLength);
Map<Character, List<String>> groupedByFirstLetter = names.stream() .collect(Collectors.groupingBy(name -> name.charAt(0))); System.out.println("Grouped By First Letter: " + groupedByFirstLetter);
Map<Boolean, List<String>> partitionedByLength = names.stream() .collect(Collectors.partitioningBy(name -> name.length() > 3)); System.out.println("Partitioned By Length > 3: " + partitionedByLength);
IntSummaryStatistics stats = names.stream() .collect(Collectors.summarizingInt(String::length)); System.out.println("Statistics: " + stats);
Set<String> nameSet = names.stream() .collect(Collectors.toSet()); System.out.println("Names as Set: " + nameSet);
Map<String, Integer> nameLengthMap = names.stream() .distinct() .collect(Collectors.toMap(name -> name, String::length)); System.out.println("Names and Their Lengths: " + nameLengthMap); } }
|
总结
Java 8 的 Stream API 提供了强大的聚合操作,可以方便地对集合进行各种复杂的操作,包括过滤、映射、归约、分组和统计等。通过掌握这些操作,可以编写出简洁、高效且易于维护的代码。