enyang
enyang
Published on 2025-06-06 / 6 Visits
0
0

Java8 stream流

Java 8 的 Stream API 是处理集合数据的函数式编程工具,提供高效、声明式的数据处理能力。以下是核心概念和用法详解:

1. 核心特点

  • 声明式编程:描述"做什么"而非"如何做"

  • 不修改源数据:生成新数据流

  • 惰性求值:中间操作延迟执行,终端操作触发计算

  • 可并行化parallelStream() 自动并行处理

2. 操作分类

类型

操作

示例

创建流

stream(), Arrays.stream(), Stream.of(), Stream.iterate()

List.stream()

中间操作

filter(), map(), flatMap(), distinct(), sorted(), limit()

filter(s -> s.length() > 3)

终端操作

forEach(), collect(), reduce(), count(), anyMatch(), findFirst()

collect(Collectors.toList())

3. 常用操作示例

3.1 过滤与映射

List<String> words = Arrays.asList("apple", "banana", "cherry", "date");
​
// 过滤长度>5并转为大写
List<String> result = words.stream()
    .filter(s -> s.length() > 5)
    .map(String::toUpperCase)
    .collect(Collectors.toList()); 
// 输出: [BANANA, CHERRY]

3.2 扁平化处理(flatMap

List<List<Integer>> numberLists = Arrays.asList(
    Arrays.asList(1, 2),
    Arrays.asList(3, 4, 5)
);
​
List<Integer> flatList = numberLists.stream()
    .flatMap(List::stream)
    .collect(Collectors.toList());
// 输出: [1, 2, 3, 4, 5]

3.3 归约操作(reduce

int sum = IntStream.range(1, 5)  // [1,2,3,4]
                .reduce(0, (a, b) -> a + b); 
// 输出: 10

3.4聚合统计

IntSummaryStatistics stats = Stream.of(1, 4, 2, 7)
    .mapToInt(Integer::intValue)
    .summaryStatistics();
​
System.out.println("Avg: " + stats.getAverage());  // 3.5
System.out.println("Max: " + stats.getMax());      // 7

4. 并行流处理

long count = words.parallelStream()
    .filter(s -> s.contains("a"))
    .count();  // 并行统计包含"a"的单词数

5. 收集器(Collectors)常用操作

收集器

功能

Collectors.toList()

转为List

Collectors.toSet()

转为Set

Collectors.joining(", ")

拼接字符串

Collectors.groupingBy()

按条件分组

Collectors.partitioningBy()

按布尔条件分区

分组示例

Map<Integer, List<String>> byLength = words.stream()
    .collect(Collectors.groupingBy(String::length));
// 输出: {5=[apple], 6=[banana, cherry], 4=[date]}

6. 注意事项

  1. 流不可复用:终端操作后流即关闭

    Stream<Integer> stream = Stream.of(1, 2);
    stream.forEach(System.out::print);  // 正常
    stream.count();  // 抛出 IllegalStateException
  2. 避免副作用:操作中不要修改外部状态

    // 错误示范 (修改外部列表)
    List<String> output = new ArrayList<>();
    words.stream().filter(s -> s.length() > 4).forEach(output::add);
    ​
    // 正确方式
    List<String> output = words.stream()
                            .filter(s -> s.length() > 4)
                            .collect(Collectors.toList());
  3. 无限流处理:使用 limit() 截断

    Stream.iterate(0, n -> n + 2)
          .limit(5)  // 限制数量
          .forEach(System.out::println);  // 0,2,4,6,8

7. 性能建议

  • 小数据量优先使用常规循环

  • 顺序无关时用并行流加速

  • 避免在流中频繁装箱(优先使用 IntStream/LongStream

Stream API 通过链式调用简化集合操作,结合 Lambda 表达式可显著提升代码可读性和简洁性,是大数据处理的高效工具。


Comment