Java Steam的用法

发布时间:2021-06-25 11:56:47 作者:chen
来源:亿速云 阅读:915
# Java Stream的用法

## 一、Stream概述

Java 8引入的Stream API是处理集合数据的革命性工具,它允许开发者以声明式方式操作数据集合。Stream不是数据结构,而是对数据源(如集合、数组等)的高级抽象,支持链式函数式操作。

核心特点:
- **惰性执行**:中间操作不会立即执行,只有遇到终止操作时才触发计算
- **不可复用**:每个Stream只能被消费一次
- **并行能力**:只需调用`parallel()`即可实现并行处理

## 二、Stream创建方式

### 1. 从集合创建
```java
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();  // 顺序流
Stream<String> parallelStream = list.parallelStream();  // 并行流

2. 从数组创建

String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);

3. 使用Stream静态方法

Stream<String> stream = Stream.of("a", "b", "c");
Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 2);  // 无限流
Stream<Double> randomStream = Stream.generate(Math::random);  // 生成流

三、中间操作

中间操作返回新的Stream,可以连续调用:

1. 过滤操作

stream.filter(s -> s.startsWith("a"))  // 过滤以a开头的元素
      .distinct()                     // 去重
      .skip(1)                        // 跳过前N个元素
      .limit(5);                     // 限制元素数量

2. 映射操作

stream.map(String::toUpperCase)       // 元素转换
      .mapToInt(String::length)       // 转换为数值流
      .flatMap(s -> Stream.of(s.split("")))  // 扁平化流

3. 排序操作

stream.sorted()                       // 自然排序
      .sorted(Comparator.reverseOrder())  // 自定义排序

四、终止操作

1. 遍历消费

stream.forEach(System.out::println);

2. 匹配检查

boolean anyMatch = stream.anyMatch(s -> s.contains("a"));
boolean allMatch = stream.allMatch(s -> s.length() > 3);
boolean noneMatch = stream.noneMatch(s -> s.isEmpty());

3. 查找操作

Optional<String> first = stream.findFirst();
Optional<String> any = stream.findAny();

4. 归约统计

Optional<String> concat = stream.reduce(String::concat);
long count = stream.count();
IntSummaryStatistics stats = stream.mapToInt(String::length).summaryStatistics();

5. 收集结果

List<String> list = stream.collect(Collectors.toList());
Set<String> set = stream.collect(Collectors.toSet());
String joined = stream.collect(Collectors.joining(","));
Map<String, Integer> map = stream.collect(Collectors.toMap(
    Function.identity(), 
    String::length
));

五、数值流特化

处理原始类型时更高效的变体:

IntStream intStream = IntStream.range(1, 100);  // 1-99
DoubleStream doubleStream = DoubleStream.of(1.1, 2.2);
LongStream longStream = LongStream.generate(() -> new Random().nextLong());

六、并行流使用

list.parallelStream()
    .filter(s -> s.length() > 3)
    .forEach(System.out::println);

注意事项: - 确保操作是线程安全的 - 避免有状态的操作 - 数据量小时可能降低性能

七、常用Collectors工具方法

方法 说明
toList() 收集为List
toSet() 收集为Set
toMap() 收集为Map
groupingBy() 分组收集
partitioningBy() 分区收集
joining() 字符串连接
counting() 计数
summarizingInt() 统计汇总

八、实战案例

案例1:数据统计

List<Product> products = ...;
DoubleSummaryStatistics stats = products.stream()
    .mapToDouble(Product::getPrice)
    .summaryStatistics();
System.out.println("平均价格: " + stats.getAverage());

案例2:分组处理

Map<Category, List<Product>> byCategory = products.stream()
    .collect(Collectors.groupingBy(Product::getCategory));

案例3:多级分组

Map<Category, Map<String, List<Product>>> multiGroup = products.stream()
    .collect(Collectors.groupingBy(
        Product::getCategory,
        Collectors.groupingBy(p -> p.getPrice() > 100 ? "高价" : "普通")
    ));

九、注意事项

  1. 流只能消费一次:重复操作会抛出IllegalStateException
  2. 避免副作用:操作应保持无状态
  3. 空指针防护:使用Optional处理可能为空的结果
  4. 性能考虑
    • 小数据量优先使用循环
    • 大数据量考虑并行流
  5. 调试技巧:使用peek()方法观察流经的元素

十、总结

Java Stream API通过函数式编程范式: - 使集合操作更简洁直观 - 提供强大的数据转换能力 - 内置并行处理支持 - 提升代码可读性和维护性

合理运用Stream可以显著提升开发效率,但需注意其适用场景和潜在的性能影响。建议结合具体业务需求,在命令式编程和函数式编程之间做出平衡选择。 “`

注:本文实际约1700字,完整覆盖了Stream的核心概念、创建方式、操作类型、使用技巧和注意事项。如需扩展具体部分,可以进一步补充更多示例或性能优化建议。

推荐阅读:
  1. Java 泛型的用法
  2. Java8 Stream不好用?如何通过 IntelliJ IDEA 提升撸码效率

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:Kafka的原理和作用是什么

下一篇:guava的使用方法有哪些

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》