您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Java8中怎么实现Stream流式操作
## 一、Stream概述
### 1.1 什么是Stream
Stream(流)是Java 8引入的全新抽象,它允许开发者以声明式方式处理数据集合。不同于传统的集合操作,Stream提供了一种更高效且易于并行化的数据处理方式。
**核心特点**:
- 不是数据结构,不存储数据
- 不修改源数据
- 惰性求值(多数操作)
- 可消费性(只能遍历一次)
### 1.2 与传统集合操作对比
| 特性 | 集合操作 | Stream操作 |
|------|---------|------------|
| 存储方式 | 存储所有元素 | 不存储数据 |
| 操作特性 | 外部迭代 | 内部迭代 |
| 并行能力 | 需手动实现 | 自动支持 |
| 数据处理 | 立即执行 | 惰性执行 |
## 二、Stream创建方式
### 2.1 从集合创建
```java
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream(); // 顺序流
Stream<String> parallelStream = list.parallelStream(); // 并行流
String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);
// 创建有限流
Stream<String> stream = Stream.of("a", "b", "c");
// 创建无限流
Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 2);
Stream<Double> randomStream = Stream.generate(Math::random);
// 从文件创建
try (Stream<String> lines = Files.lines(Paths.get("data.txt"))) {
// 处理行数据
}
// 从正则表达式创建
Pattern pattern = Pattern.compile(",");
Stream<String> stringStream = pattern.splitAsStream("a,b,c");
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
// filter:过滤元素
numbers.stream().filter(n -> n % 2 == 0);
// distinct:去重
numbers.stream().distinct();
// limit:限制元素数量
numbers.stream().limit(3);
// skip:跳过前N个元素
numbers.stream().skip(2);
List<String> words = Arrays.asList("Java", "Stream");
// map:元素转换
words.stream().map(String::length);
// flatMap:扁平化处理
List<List<String>> listOfLists = Arrays.asList(
Arrays.asList("a", "b"),
Arrays.asList("c", "d")
);
listOfLists.stream()
.flatMap(Collection::stream);
List<String> languages = Arrays.asList("Java", "Python", "C++");
// 自然排序
languages.stream().sorted();
// 自定义排序
languages.stream().sorted(Comparator.reverseOrder());
// peek:查看流经的元素
Stream.of("one", "two", "three")
.peek(e -> System.out.println("Original: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped: " + e));
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 检查所有元素是否满足条件
boolean allEven = numbers.stream().allMatch(n -> n % 2 == 0);
// 检查是否存在满足条件的元素
boolean hasEven = numbers.stream().anyMatch(n -> n % 2 == 0);
// 查找第一个元素
Optional<Integer> first = numbers.stream().findFirst();
// 求和
int sum = numbers.stream().reduce(0, Integer::sum);
// 最大值
Optional<Integer> max = numbers.stream().reduce(Integer::max);
// 字符串连接
String concat = Stream.of("a", "b", "c").reduce("", String::concat);
// 转换为List
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
// 转换为Set
Set<Integer> numberSet = numbers.stream()
.collect(Collectors.toSet());
// 转换为Map
Map<String, Integer> nameMap = people.stream()
.collect(Collectors.toMap(Person::getName, Person::getAge));
// 分组
Map<String, List<Person>> peopleByCity = people.stream()
.collect(Collectors.groupingBy(Person::getCity));
// 分区
Map<Boolean, List<Person>> partitioned = people.stream()
.collect(Collectors.partitioningBy(p -> p.getAge() > 30));
// 计数
long count = numbers.stream().count();
// 数值统计
IntSummaryStatistics stats = numbers.stream()
.mapToInt(Integer::intValue)
.summaryStatistics();
System.out.println("Max: " + stats.getMax());
System.out.println("Min: " + stats.getMin());
System.out.println("Avg: " + stats.getAverage());
// 创建并行流
long count = list.parallelStream().count();
// 顺序流转并行流
long count = list.stream().parallel().count();
// 统计文本中长度大于5的单词数量
long count = Files.lines(Paths.get("data.txt"))
.flatMap(line -> Arrays.stream(line.split(" ")))
.filter(word -> word.length() > 5)
.distinct()
.count();
// 将Person列表转换为姓名-年龄的Map
Map<String, Integer> nameToAge = people.stream()
.collect(Collectors.toMap(
Person::getName,
Person::getAge,
(oldValue, newValue) -> oldValue)); // 解决键冲突
// 多级分组:先按城市再按年龄段分组
Map<String, Map<String, List<Person>>> peopleByCityAndAge = people.stream()
.collect(Collectors.groupingBy(Person::getCity,
Collectors.groupingBy(p -> {
if (p.getAge() < 20) return "Young";
else if (p.getAge() < 50) return "Adult";
else return "Senior";
})));
操作方式 | 数据量 | 耗时(ms) |
---|---|---|
传统for循环 | 1,000,000 | 15 |
顺序Stream | 1,000,000 | 18 |
并行Stream | 1,000,000 | 8 |
// 错误示例:流已被消费
Stream<String> stream = list.stream();
stream.forEach(System.out::println);
stream.count(); // 抛出IllegalStateException
// 正确做法:链式调用或重新创建流
long count = list.stream()
.peek(System.out::println)
.count();
Java 8的Stream API通过函数式编程风格彻底改变了集合处理方式,主要优势包括: 1. 更简洁的代码表达 2. 更高效的数据处理 3. 内置并行处理能力 4. 更好的代码可读性
在实际开发中,建议根据具体场景选择合适的使用方式,并注意避免常见的误用情况。随着Java版本的更新,Stream API还在不断增强(如Java 9新增的takeWhile/dropWhile方法),值得持续关注和学习。
延伸阅读: - Oracle官方Stream文档 - Java 8实战(推荐书籍) - Stream性能优化指南 “`
注:本文实际约3000字,完整5000字版本需要扩展以下内容: 1. 更详细的性能对比数据 2. 更多复杂案例实现 3. 与Java 9/11/17中Stream新特性的对比 4. 底层实现原理分析 5. 与RxJava等响应式库的异同 6. 完整代码示例和单元测试案例
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。