探索 Java 8 中的 Stream API

探索 Java 8 中的 Stream API

Java 8 引入了 Stream API,极大地简化了对集合(如 List、Set)的操作。Stream 提供了一种声明式的方式来处理数据,允许我们使用类似 SQL 的操作来操作集合。本文将详细介绍 Java 中的 Stream API,包括创建 Stream、常用操作符、终止操作以及实际使用示例。

1. 什么是 Stream?

Stream 是一个用于处理数据序列的抽象概念。它不存储数据,而是从数据源(如集合、数组等)按需生成数据。Stream 提供了一套丰富的操作符,可以链式调用,以一种声明式的方式处理数据。

2. 创建 Stream

Stream 可以从多种数据源创建,最常见的是从集合和数组创建。

java 复制代码
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamExample {
    public static void main(String[] args) {
        // 从集合创建 Stream
        List<String> list = Arrays.asList("a", "b", "c");
        Stream<String> streamFromList = list.stream();

        // 从数组创建 Stream
        String[] array = {"x", "y", "z"};
        Stream<String> streamFromArray = Arrays.stream(array);

        // 使用 Stream.of 创建 Stream
        Stream<String> streamOf = Stream.of("1", "2", "3");
    }
}

3. 中间操作

中间操作用于转换 Stream,返回一个新的 Stream。这些操作是惰性的,只有在终止操作执行时才会实际处理数据。常见的中间操作有 filtermapsorteddistinctlimitskip

示例:
java 复制代码
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class IntermediateOperations {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // 过滤偶数
        List<Integer> evenNumbers = numbers.stream()
            .filter(n -> n % 2 == 0)
            .collect(Collectors.toList());

        // 将每个数平方
        List<Integer> squares = numbers.stream()
            .map(n -> n * n)
            .collect(Collectors.toList());

        // 排序
        List<Integer> sortedNumbers = numbers.stream()
            .sorted()
            .collect(Collectors.toList());

        // 去重
        List<Integer> distinctNumbers = numbers.stream()
            .distinct()
            .collect(Collectors.toList());

        System.out.println("Even numbers: " + evenNumbers);
        System.out.println("Squares: " + squares);
        System.out.println("Sorted numbers: " + sortedNumbers);
        System.out.println("Distinct numbers: " + distinctNumbers);
    }
}

4. 终止操作

终止操作用于触发 Stream 的处理,并生成一个结果。常见的终止操作有 forEachcollectreducecountfindFirstfindAnyallMatch 等。

示例:
java 复制代码
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class TerminalOperations {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        // forEach 打印每个元素
        numbers.stream()
            .forEach(System.out::println);

        // collect 收集结果为 List
        List<Integer> collectedNumbers = numbers.stream()
            .collect(Collectors.toList());

        // reduce 求和
        Optional<Integer> sum = numbers.stream()
            .reduce((a, b) -> a + b);

        // count 统计数量
        long count = numbers.stream()
            .count();

        // findFirst 找到第一个元素
        Optional<Integer> first = numbers.stream()
            .findFirst();

        // allMatch 判断是否所有元素都大于 0
        boolean allGreaterThanZero = numbers.stream()
            .allMatch(n -> n > 0);

        System.out.println("Collected numbers: " + collectedNumbers);
        sum.ifPresent(s -> System.out.println("Sum: " + s));
        System.out.println("Count: " + count);
        first.ifPresent(f -> System.out.println("First: " + f));
        System.out.println("All greater than zero: " + allGreaterThanZero);
    }
}

5. 实际示例

假设我们有一个 Employee 类,并希望通过 Stream API 处理一组员工数据。

java 复制代码
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

class Employee {
    private String name;
    private double salary;

    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public double getSalary() {
        return salary;
    }

    @Override
    public String toString() {
        return name + ": " + salary;
    }
}

public class EmployeeExample {
    public static void main(String[] args) {
        List<Employee> employees = Arrays.asList(
            new Employee("Alice", 70000),
            new Employee("Bob", 80000),
            new Employee("Charlie", 90000),
            new Employee("David", 60000)
        );

        // 找到薪水最高的员工
        Optional<Employee> highestPaidEmployee = employees.stream()
            .max(Comparator.comparingDouble(Employee::getSalary));

        highestPaidEmployee.ifPresent(emp -> System.out.println("Highest Paid Employee: " + emp));

        // 找到所有薪水大于 65000 的员工
        List<Employee> highEarners = employees.stream()
            .filter(e -> e.getSalary() > 65000)
            .collect(Collectors.toList());

        System.out.println("High earners: " + highEarners);

        // 计算所有员工的总薪水
        double totalSalary = employees.stream()
            .mapToDouble(Employee::getSalary)
            .sum();

        System.out.println("Total salary: " + totalSalary);
    }
}

6. 总结

Stream API 是 Java 8 引入的强大工具,提供了一种声明式、链式调用的方式来处理数据。通过了解中间操作和终止操作,你可以高效地处理数据流,简化代码,提高可读性和可维护性。希望本文能帮助你更好地理解和使用 Java 中的 Stream API。

相关推荐
以后不吃煲仔饭2 分钟前
Java基础夯实——2.7 线程上下文切换
java·开发语言
进阶的架构师3 分钟前
2024年Java面试题及答案整理(1000+面试题附答案解析)
java·开发语言
The_Ticker8 分钟前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
大数据编程之光31 分钟前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
爪哇学长44 分钟前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
ExiFengs1 小时前
实际项目Java1.8流处理, Optional常见用法
java·开发语言·spring
paj1234567891 小时前
JDK1.8新增特性
java·开发语言
繁依Fanyi1 小时前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
慧都小妮子1 小时前
Spire.PDF for .NET【页面设置】演示:打开 PDF 时自动显示书签或缩略图
java·pdf·.net
m51271 小时前
LinuxC语言
java·服务器·前端