Stream流知识点总结

Steam流是Java 8引入的一个强大的API,用于处理集合数据的函数式编程方式。以下是关于Steam流的主要知识点总结:

1. 基本概念

  • Stream:不是数据结构,而是对数据源(集合、数组等)的高级抽象,用于高效处理大量数据
  • 特点
    • 不存储数据(只是数据源的视图)
    • 不修改源数据(操作会产生新Stream)
    • 惰性执行(终端操作时才执行)
    • 可消费性(Stream只能被消费一次)

2. 创建Stream的方式

java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 从集合创建
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();

// 从数组创建
String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);

// 使用Stream.of()
Stream<String> stream = Stream.of("a", "b", "c");

// 创建无限流
Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 2); // 无限流
Stream<Double> randomStream = Stream.generate(Math::random); // 无限随机数流

3. 中间操作(Intermediate Operations)

  • **filter(Predicate)**:过滤元素
  • **map(Function)**:转换元素
  • **flatMap(Function)**:扁平化流(将流中的每个值转换为另一个流)
  • **distinct()**:去重
  • **sorted()**:排序
  • **limit(long)**:限制元素数量
  • **skip(long)**:跳过前N个元素
  • **peek(Consumer)**:查看流中元素(主要用于调试)

4. 终端操作(Terminal Operations)

  • **forEach(Consumer)**:遍历每个元素
  • **count()**:计数
  • **collect(Collector)**:将流转换为集合或其他形式
  • **reduce(BinaryOperator)**:归约操作
  • **min(Comparator)/max(Comparator)**:查找最小/最大值
  • **anyMatch(Predicate)/allMatch(Predicate)/noneMatch(Predicate)**:匹配检查
  • **findFirst()/findAny()**:查找元素

5. 收集器(Collectors)

常用Collectors方法:

  • **toList()/toSet()/toCollection()**:转换为集合
  • **joining()**:连接字符串
  • **summingInt()/averagingInt()**:求和/平均值
  • **groupingBy()**:分组
  • **partitioningBy()**:分区
  • **counting()**:计数

6. 并行流(Parallel Stream)

  • 使用parallelStream()stream().parallel()创建并行流
  • 适用于大数据量且无状态的操作
  • 注意线程安全问题

7. 使用示例

java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 示例1: 过滤和映射
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> result = names.stream()
.filter(name -> name.length() > 3)
.map(String::toUpperCase)
.collect(Collectors.toList());

// 示例2: 分组
Map<Integer, List<String>> groupByNameLength = names.stream()
.collect(Collectors.groupingBy(String::length));

// 示例3: 归约
Optional<Integer> totalLength = names.stream()
.map(String::length)
.reduce(Integer::sum);

8. 注意事项

  1. Stream操作是延迟执行的,只有终端操作才会触发实际计算
  2. Stream只能被消费一次,再次使用会抛出IllegalStateException
  3. 避免在流操作中修改源数据
  4. 对于简单操作,传统循环可能比Stream更高效

Stream API极大地简化了集合操作,使代码更简洁、易读,特别适合复杂的数据处理场景。