跳转到内容

Java Stream概述

来自代码酷

Java Stream概述[编辑 | 编辑源代码]

Java Stream API是Java 8引入的一个强大的功能,用于以声明式的方式处理数据集合。它允许开发者以更简洁、更易读的方式编写数据处理代码,同时支持并行操作以提高性能。Stream API不是数据结构,而是对数据源(如集合、数组或I/O资源)的高层抽象,可以进行复杂的操作如过滤、映射、排序和聚合。

核心概念[编辑 | 编辑源代码]

Stream API基于以下几个关键概念:

  • 流(Stream):一个来自数据源的元素序列,支持聚合操作。
  • 中间操作(Intermediate Operations):返回新流的操作,如filter、map、sorted等,可以链式调用。
  • 终端操作(Terminal Operations):产生结果或副作用的操作,如forEach、collect、reduce等,会关闭流。

流的特点[编辑 | 编辑源代码]

  • 不存储数据:流本身不存储元素,而是从数据源(如集合)获取数据。
  • 函数式风格:操作不会修改源数据,而是返回新的流。
  • 惰性求值:中间操作不会立即执行,直到终端操作被调用。
  • 可消费性:流只能被消费一次,终端操作后流即关闭。

创建流[编辑 | 编辑源代码]

可以通过多种方式创建流:

// 从集合创建
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream1 = list.stream();

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

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

// 生成无限流
Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 2);

常用操作示例[编辑 | 编辑源代码]

过滤(filter)[编辑 | 编辑源代码]

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> result = names.stream()
    .filter(name -> name.length() > 4)
    .collect(Collectors.toList());
// 输出: [Alice, Charlie, David]

映射(map)[编辑 | 编辑源代码]

List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
List<Integer> squares = numbers.stream()
    .map(n -> n * n)
    .collect(Collectors.toList());
// 输出: [1, 4, 9, 16]

排序(sorted)[编辑 | 编辑源代码]

List<String> names = Arrays.asList("Charlie", "Alice", "Bob");
List<String> sortedNames = names.stream()
    .sorted()
    .collect(Collectors.toList());
// 输出: [Alice, Bob, Charlie]

聚合(reduce)[编辑 | 编辑源代码]

List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
int sum = numbers.stream()
    .reduce(0, (a, b) -> a + b);
// 输出: 10

并行流[编辑 | 编辑源代码]

Stream API支持并行处理,可以轻松利用多核处理器:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int sum = numbers.parallelStream()
    .filter(n -> n % 2 == 0)
    .mapToInt(Integer::intValue)
    .sum();
// 输出: 30

实际应用案例[编辑 | 编辑源代码]

案例1:数据处理[编辑 | 编辑源代码]

处理员工数据,筛选出薪资高于平均值的员工:

class Employee {
    String name;
    double salary;
    // 构造方法、getter/setter省略
}

List<Employee> employees = Arrays.asList(
    new Employee("Alice", 50000),
    new Employee("Bob", 60000),
    new Employee("Charlie", 45000)
);

double averageSalary = employees.stream()
    .mapToDouble(Employee::getSalary)
    .average()
    .orElse(0.0);

List<Employee> aboveAverage = employees.stream()
    .filter(e -> e.getSalary() > averageSalary)
    .collect(Collectors.toList());

案例2:文件处理[编辑 | 编辑源代码]

读取文件并统计单词出现频率:

Path path = Paths.get("sample.txt");
Map<String, Long> wordCount = Files.lines(path)
    .flatMap(line -> Arrays.stream(line.split("\\s+")))
    .collect(Collectors.groupingBy(
        String::toLowerCase,
        Collectors.counting()
    ));

流操作流程图[编辑 | 编辑源代码]

graph LR A[数据源] --> B[创建流] B --> C[中间操作] C --> D[终端操作] C -->|filter| C C -->|map| C C -->|sorted| C C -->|其他操作| C D --> E[结果/副作用]

数学基础[编辑 | 编辑源代码]

Stream API中的一些操作有数学基础,例如reduce操作类似于数学中的求和:

i=1nxi=x1+x2++xn

在Java中表示为:

numbers.stream().reduce(0, (a, b) -> a + b);

性能考虑[编辑 | 编辑源代码]

  • 对于小数据集,顺序流可能更快
  • 对于大数据集,并行流可以显著提高性能
  • 注意中间操作的开销,如sorted可能导致性能下降

总结[编辑 | 编辑源代码]

Java Stream API提供了一种高效、声明式的方式来处理数据集合。通过理解其核心概念和操作,开发者可以编写更简洁、更易维护的代码。Stream API特别适合数据处理、转换和聚合任务,是现代Java编程中不可或缺的工具。