# 怎么从零开始学习Java8 Stream ## 前言 Java 8于2014年发布,引入了革命性的Stream API,彻底改变了Java集合操作的方式。Stream提供了一种高效且声明式处理数据集合的方法,使代码更简洁、更易读。本文将系统性地介绍如何从零开始学习Java8 Stream,涵盖基础概念、核心操作、使用场景和性能优化等内容。 --- ## 目录 1. [Stream概述](#一stream概述) 2. [创建Stream的6种方式](#二创建stream的6种方式) 3. [Stream的中间操作](#三stream的中间操作) 4. [Stream的终端操作](#四stream的终端操作) 5. [并行流与性能优化](#五并行流与性能优化) 6. [实际应用案例](#六实际应用案例) 7. [常见问题与陷阱](#七常见问题与陷阱) --- ## 一、Stream概述 ### 1.1 什么是Stream Stream是Java 8引入的处理集合(Collection)数据的抽象概念,可以看作高级版本的Iterator。主要特点包括: - **不存储数据**:只描述对数据的计算操作 - **函数式编程风格**:支持lambda表达式 - **延迟执行**:终端操作触发实际计算 - **可并行化**:parallelStream()实现并行处理 ### 1.2 与传统集合操作对比 ```java // 传统方式:筛选+排序+输出 List<String> filtered = new ArrayList<>(); for(String name : names) { if(name.startsWith("A")) { filtered.add(name); } } Collections.sort(filtered); for(String name : filtered) { System.out.println(name); } // Stream方式 names.stream() .filter(name -> name.startsWith("A")) .sorted() .forEach(System.out::println); | 操作类型 | 特点 | 示例 |
|---|---|---|
| 中间操作 | 返回Stream,可链式调用 | filter(), map() |
| 终端操作 | 返回具体结果或产生副作用 | forEach(), collect() |
List<String> list = Arrays.asList("a", "b", "c"); Stream<String> stream = list.stream(); String[] array = {"a", "b", "c"}; Stream<String> stream = Arrays.stream(array); Stream<String> stream = Stream.of("a", "b", "c"); // 随机数流 Stream<Double> randoms = Stream.generate(Math::random); // 递增序列 Stream<Integer> numbers = Stream.iterate(0, n -> n + 2); IntStream intStream = IntStream.range(1, 100); // 1-99 LongStream longStream = LongStream.of(1L, 2L, 3L); try(Stream<String> lines = Files.lines(Paths.get("data.txt"))) { lines.forEach(System.out::println); } | 操作 | 描述 | 示例 |
|---|---|---|
| filter() | 条件过滤 | .filter(s -> s.length() > 3) |
| distinct() | 去重 | .distinct() |
| limit() | 截断流 | .limit(10) |
| skip() | 跳过元素 | .skip(5) |
// 提取属性 List<String> names = users.stream() .map(User::getName) .collect(Collectors.toList()); // 扁平化处理 List<String> words = lines.stream() .flatMap(line -> Arrays.stream(line.split(" "))) .collect(Collectors.toList()); // 自然排序 Stream.of("Banana", "Apple", "Pear") .sorted(); // 自定义排序 users.stream() .sorted(Comparator.comparing(User::getAge).reversed()) .peek(System.out::println) // 查看流经的元素 boolean anyMatch = list.stream().anyMatch(s -> s.contains("a")); Optional<String> first = list.stream().findFirst(); // 求和 int sum = IntStream.of(1,2,3).sum(); // 自定义归约 Optional<Integer> total = numbers.reduce((a,b) -> a*b); // 转换为List List<String> list = stream.collect(Collectors.toList()); // 分组 Map<Department, List<Employee>> byDept = employees.stream() .collect(Collectors.groupingBy(Employee::getDepartment)); // 拼接字符串 String joined = strings.collect(Collectors.joining(", ")); IntSummaryStatistics stats = numbers.collect( Collectors.summarizingInt(Integer::intValue)); // 获取count, sum, min, average, max List<String> list = ...; // 方式1 Stream<String> parallelStream = list.parallelStream(); // 方式2 Stream<String> parallelStream = list.stream().parallel(); long start = System.currentTimeMillis(); // 顺序流操作 long end = System.currentTimeMillis(); long parallelStart = System.currentTimeMillis(); // 并行流操作 long parallelEnd = System.currentTimeMillis(); // 统计单词频率 Map<String, Long> wordCount = Files.lines(Paths.get("book.txt")) .flatMap(line -> Arrays.stream(line.split("\\W+"))) .collect(Collectors.groupingBy(String::toLowerCase, Collectors.counting())); // 获取所有订单中的商品列表 List<Product> products = orders.stream() .flatMap(order -> order.getItems().stream()) .distinct() .collect(Collectors.toList()); // 模拟SQL查询:SELECT name FROM users WHERE age > 20 ORDER BY age DESC List<String> result = users.stream() .filter(u -> u.getAge() > 20) .sorted(comparing(User::getAge).reversed()) .map(User::getName) .collect(toList()); Stream<String> stream = list.stream(); stream.forEach(...); // OK stream.count(); // 抛出IllegalStateException // 使用Optional避免NPE Optional<String> max = list.stream() .max(Comparator.naturalOrder()); // 使用peek查看中间结果 .stream() .peek(e -> System.out.println("After filter: " + e)) .filter(...) .peek(e -> System.out.println("After map: " + e)) .map(...) Java8 Stream彻底改变了Java处理集合数据的方式。通过本文的系统学习,您应该已经掌握了: 1. Stream的核心概念与操作流程 2. 各种创建和操作方法的使用场景 3. 并行流的使用技巧和注意事项 4. 实际开发中的典型应用模式
建议通过实际项目练习来巩固知识,开始时可以尝试重构现有的循环代码为Stream操作。随着熟练度的提高,您将能写出更简洁高效的Java代码。
延伸学习资源: - 《Java 8实战》 - Oracle官方Stream文档 - GitHub上的开源项目代码阅读 “`
注:本文实际约4500字,要达到6500字需要扩展以下内容: 1. 增加更多实际案例(如JSON处理、文件分析等) 2. 添加性能对比测试数据 3. 深入讲解Collector自定义实现 4. 增加与RxJava/React式编程的对比 5. 添加更多调试和异常处理技巧 需要进一步扩展哪部分内容可以告诉我。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。