← 返回首页

Java Stream API详解

📂 java ⏱ 4 min 606 words

Java Stream API详解

什么是Stream

Stream是Java 8引入的用于处理集合数据的API,支持声明式、函数式的编程风格。

创建Stream

public class StreamCreation {
    public static void main(String[] args) {
        // 1. 从集合创建
        List<String> list = List.of("a", "b", "c");
        Stream<String> stream1 = list.stream();
        Stream<String> parallelStream1 = list.parallelStream();

        // 2. 从数组创建
        int[] arr = {1, 2, 3, 4, 5};
        IntStream stream2 = Arrays.stream(arr);

        // 3. 直接创建
        Stream<String> stream3 = Stream.of("x", "y", "z");
        Stream<Integer> stream4 = Stream.of(1, 2, 3);

        // 4. 生成无限流
        Stream<Double> randoms = Stream.generate(Math::random).limit(5);
        Stream<Integer> naturals = Stream.iterate(1, n -> n + 1).limit(10);

        // 5. 从文件创建
        Stream<String> lines = Files.lines(Path.of("data.txt"));
    }
}

中间操作

public class StreamTransform {
    public static void main(String[] args) {
        List<String> names = List.of("Alice", "Bob", "Charlie", "David", "Eve");

        // filter:过滤
        List<String> longNames = names.stream()
            .filter(name -> name.length() > 3)
            .toList();
        // [Alice, Charlie, David]

        // map:转换
        List<String> upperNames = names.stream()
            .map(String::toUpperCase)
            .toList();
        // [ALICE, BOB, CHARLIE, DAVID, EVE]

        // flatMap:扁平化映射
        List<List<Integer>> nested = List.of(
            List.of(1, 2), List.of(3, 4), List.of(5, 6)
        );
        List<Integer> flat = nested.stream()
            .flatMap(Collection::stream)
            .toList();
        // [1, 2, 3, 4, 5, 6]

        // distinct:去重
        List<Integer> numbers = List.of(1, 2, 2, 3, 3, 4);
        List<Integer> unique = numbers.stream()
            .distinct()
            .toList();
        // [1, 2, 3, 4]

        // sorted:排序
        List<String> sorted = names.stream()
            .sorted()
            .toList();

        // peek:调试查看
        List<String> result = names.stream()
            .filter(name -> name.length() > 3)
            .peek(name -> System.out.println("过滤后: " + name))
            .map(String::toLowerCase)
            .toList();

        // limit & skip:分页
        List<String> page = names.stream()
            .skip(2)
            .limit(2)
            .toList();
        // [Charlie, David]
    }
}

终端操作

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

        // collect:收集结果
        List<Integer> evens = numbers.stream()
            .filter(n -> n % 2 == 0)
            .collect(Collectors.toList());

        // toList
        List<String> names = List.of("Alice", "Bob", "Charlie");
        List<String> upper = names.stream()
            .map(String::toUpperCase)
            .toList();

        // joining
        String joined = names.stream()
            .collect(Collectors.joining(", "));
        // "Alice, Bob, Charlie"

        // groupingBy
        List<String> words = List.of("apple", "banana", "cherry", "avocado");
        Map<Character, List<String>> grouped = words.stream()
            .collect(Collectors.groupingBy(w -> w.charAt(0)));
        // {a=[apple, avocado], b=[banana], c=[cherry]}

        // counting
        long count = numbers.stream()
            .filter(n -> n > 5)
            .count();

        // summing
        int sum = numbers.stream()
            .mapToInt(Integer::intValue)
            .sum();

        // reduce
        int product = numbers.stream()
            .reduce(1, (a, b) -> a * b);

        Optional<Integer> max = numbers.stream()
            .max(Integer::compareTo);

        Optional<Integer> min = numbers.stream()
            .min(Integer::compareTo);

        // forEach
        numbers.stream()
            .filter(n -> n % 2 == 0)
            .forEach(System.out::println);

        // toArray
        Integer[] array = numbers.stream()
            .toArray(Integer[]::new);
    }
}

Collectors高级用法

public class CollectorsAdvanced {
    public static void main(String[] args) {
        List<Employee> employees = List.of(
            new Employee("张三", "技术部", 8000),
            new Employee("李四", "技术部", 12000),
            new Employee("王五", "市场部", 9000),
            new Employee("赵六", "市场部", 11000)
        );

        // 分组统计
        Map<String, List<Employee>> byDept = employees.stream()
            .collect(Collectors.groupingBy(Employee::getDepartment));

        // 分组计数
        Map<String, Long> deptCount = employees.stream()
            .collect(Collectors.groupingBy(
                Employee::getDepartment,
                Collectors.counting()
            ));

        // 分组求和
        Map<String, Integer> deptSalary = employees.stream()
            .collect(Collectors.groupingBy(
                Employee::getDepartment,
                Collectors.summingInt(Employee::getSalary)
            ));

        // 分区
        Map<Boolean, List<Employee>> partitioned = employees.stream()
            .collect(Collectors.partitioningBy(e -> e.getSalary() > 10000));

        // 统计信息
        IntSummaryStatistics stats = employees.stream()
            .mapToInt(Employee::getSalary)
            .summaryStatistics();
        System.out.println("平均: " + stats.getAverage());
        System.out.println("最大: " + stats.getMax());
        System.out.println("最小: " + stats.getMin());
    }
}

并行流

public class ParallelStreamDemo {
    public static void main(String[] args) {
        List<Integer> numbers = IntStream.rangeClosed(1, 1000000).boxed().toList();

        // 串行流
        long start = System.nanoTime();
        long count = numbers.stream()
            .filter(n -> isPrime(n))
            .count();
        System.out.println("串行: " + (System.nanoTime() - start) / 1000000 + "ms");

        // 并行流
        start = System.nanoTime();
        count = numbers.parallelStream()
            .filter(n -> isPrime(n))
            .count();
        System.out.println("并行: " + (System.nanoTime() - start) / 1000000 + "ms");
    }

    private static boolean isPrime(int n) {
        if (n < 2) return false;
        for (int i = 2; i * i <= n; i++) {
            if (n % i == 0) return false;
        }
        return true;
    }
}

方法引用

public class MethodReferenceDemo {
    public static void main(String[] args) {
        List<String> names = List.of("Alice", "Bob", "Charlie");

        // 静态方法引用
        names.stream()
            .map(String::toUpperCase)
            .toList();

        // 实例方法引用
        names.stream()
            .map(String::length)
            .toList();

        // 构造器引用
        List<String> strings = List.of("1", "2", "3");
        List<Integer> integers = strings.stream()
            .map(Integer::new)
            .toList();
    }
}

总结

Stream API让集合操作更简洁、更函数式。掌握filter、map、reduce等核心操作,能大幅提升代码可读性和开发效率。