探索 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。

相关推荐
十一月十一」16 分钟前
WebDriver API
java·selenium
前端组件开发18 分钟前
基于uni-app与图鸟UI的移动应用模板构建研究
java·开发语言·前端·ui·小程序·前端框架·uni-app
weixin_8368695201 小时前
Java中的机器学习模型集成与训练
java·开发语言·机器学习
VX_DZbishe1 小时前
springboot旅游管理系统-计算机毕业设计源码16021
java·spring boot·python·servlet·django·flask·php
橙子味冰可乐1 小时前
isprintable()方法——判断字符是否为可打印字符
java·前端·javascript·数据库·python
yunpeng.zhou1 小时前
logging 模块简单使用记录
java·前端·数据库
嗨!陌生人2 小时前
SpringSecurity中文文档(Servlet Session Management)
java·hadoop·spring boot·后端·spring cloud·servlet
广西千灵通网络科技有限公司2 小时前
基于Java的微信记账小程序【附源码】
java·微信·小程序
shangjg36 小时前
如何实现高可用的分布式系统
java·分布式
G皮T7 小时前
【Spring Boot】Java 的数据库连接模板:JDBCTemplate
java·数据库·spring boot·jdbc·jdbctemplate