ITPub博客

首页 > IT职业 > IT职场 > 深入浅出Stream流:让Java集合操作飞起来

深入浅出Stream流:让Java集合操作飞起来

IT职场 作者:jiaojiaoxuan 时间:2025-11-13 15:02:42 0 删除 编辑

什么是Stream流?

Stream是Java 8中引入的一个强大的新特性,它允许我们以声明式的方式处理数据集合。想象一下,你有一箱苹果,想要找出所有红色的苹果并按大小排序。传统方式需要你一步步写循环和条件判断,而Stream则像是一条流水线,你只需要告诉它:"我要红色的苹果,按大小排序",它就会自动帮你完成。

为什么需要Stream?

在Stream出现之前,我们处理集合数据通常使用for循环或迭代器,这种方式称为 外部迭代——我们需要自己控制迭代过程。而Stream提供了 内部迭代,我们只需要关心"做什么",而不需要关心"怎么做"。

传统方式 vs Stream方式

java
// 传统方式:找出大于10的偶数并排序List<Integer> numbers = Arrays.asList(1, 2, 3, 12, 5, 6, 18, 7, 8);List<Integer> result = new ArrayList<>();for (Integer num : numbers) {
    if (num % 2 == 0 && num > 10) {
        result.add(num);
    }}Collections.sort(result);// Stream方式:同样的功能List<Integer> result = numbers.stream()
        .filter(n -> n % 2 == 0)
        .filter(n -> n > 10)
        .sorted()
        .collect(Collectors.toList());

可以看到,Stream代码更简洁、更易读,更像是在描述问题本身而不是实现细节。

Stream的核心概念

1. 创建Stream

有多种方式可以创建Stream:

java
// 从集合创建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");// 创建数字流IntStream intStream = IntStream.range(1, 5); // 1,2,3,4

2. 中间操作 vs 终止操作

Stream操作分为两类:

  • 中间操作:返回Stream本身,可以链式调用(如filter, map, sorted)

  • 终止操作:返回具体结果或执行操作(如collect, forEach, count)

java
List<String> result = list.stream()        // 创建流
        .filter(s -> s.startsWith("a"))   // 中间操作
        .map(String::toUpperCase)         // 中间操作
        .collect(Collectors.toList());    // 终止操作

3. 常用操作详解

filter - 过滤

java
// 筛选出长度大于3的字符串List<String> list = Arrays.asList("java", "py", "c", "javascript");List<String> result = list.stream()
        .filter(s -> s.length() > 3)
        .collect(Collectors.toList());// 结果: ["java", "javascript"]

map - 映射/转换

java
// 将字符串转换为大写List<String> list = Arrays.asList("java", "python");List<String> result = list.stream()
        .map(String::toUpperCase)
        .collect(Collectors.toList());// 结果: ["JAVA", "PYTHON"]// 提取对象属性List<User> users = Arrays.asList(new User("Alice", 25), new User("Bob", 30));List<String> names = users.stream()
        .map(User::getName)
        .collect(Collectors.toList());// 结果: ["Alice", "Bob"]

sorted - 排序

java
// 自然排序List<String> list = Arrays.asList("java", "python", "c");List<String> result = list.stream()
        .sorted()
        .collect(Collectors.toList());// 结果: ["c", "java", "python"]// 自定义排序List<String> result = list.stream()
        .sorted((s1, s2) -> s2.length() - s1.length()) // 按长度降序
        .collect(Collectors.toList());// 结果: ["python", "java", "c"]

distinct - 去重

java
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 3);List<Integer> result = numbers.stream()
        .distinct()
        .collect(Collectors.toList());// 结果: [1, 2, 3]

limit/skip - 限制/跳过

java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);List<Integer> result = numbers.stream()
        .skip(2)    // 跳过前2个元素
        .limit(5)   // 只取5个元素
        .collect(Collectors.toList());// 结果: [3, 4, 5, 6, 7]

4. 终止操作

collect - 收集结果

java
// 转换为ListList<String> list = stream.collect(Collectors.toList());// 转换为SetSet<String> set = stream.collect(Collectors.toSet());// 转换为MapMap<String, Integer> map = stream.collect(
    Collectors.toMap(s -> s, String::length)); // key:元素本身, value:长度// 拼接字符串String result = stream.collect(Collectors.joining(", "));

forEach - 遍历

java
// 打印每个元素stream.forEach(System.out::println);

count - 计数

java
long count = stream.filter(s -> s.length() > 3).count();

reduce - 归约

java
// 求和List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);int sum = numbers.stream().reduce(0, Integer::sum);// 结果: 15// 找出最长字符串Optional<String> longest = strings.stream()
        .reduce((s1, s2) -> s1.length() > s2.length() ? s1 : s2);

并行流:发挥多核优势

Stream的强大之处还在于可以轻松实现并行处理:

java
// 顺序流List<String> result = list.stream()...collect(Collectors.toList());// 并行流 - 自动利用多核处理器List<String> result = list.parallelStream()...collect(Collectors.toList());

只需要将 stream()改为 parallelStream(),Java会自动将任务分解到多个CPU核心上执行,大幅提升大数据集的处理速度。

实际应用示例

示例1:数据处理管道

java
// 处理用户数据:筛选活跃用户,提取用户名,排序,去重List<String> activeUserNames = users.stream()
        .filter(User::isActive)           // 筛选活跃用户
        .map(User::getName)               // 提取用户名
        .sorted()                         // 按字母排序
        .distinct()                       // 去重
        .collect(Collectors.toList());    // 收集结果

示例2:统计计算

java
// 计算产品平均价格double averagePrice = products.stream()
        .filter(p -> p.getCategory().equals("Electronics"))
        .mapToDouble(Product::getPrice)   // 转换为DoubleStream
        .average()                        // 计算平均值
        .orElse(0.0);                     // 如果无结果返回0.0

示例3:分组操作

java
// 按部门分组员工Map<String, List<Employee>> employeesByDept = employees.stream()
        .collect(Collectors.groupingBy(Employee::getDepartment));// 按城市分组并计算每个城市的平均工资Map<String, Double> avgSalaryByCity = employees.stream()
        .collect(Collectors.groupingBy(
            Employee::getCity,
            Collectors.averagingDouble(Employee::getSalary)
        ));https://zq.zhaopin.com/moment/73399625https://zq.zhaopin.com/moment/73399625    
https://zq-mobile.zhaopin.com/moment/73399625    
https://zhiq.zhaopin.com/moment/73399625    
https://zq.zhaopin.com/moment/73399619    
https://zq-mobile.zhaopin.com/moment/73399619    
https://zhiq.zhaopin.com/moment/73399619    
https://zq.zhaopin.com/moment/73399615    
https://zq-mobile.zhaopin.com/moment/73399615    
https://zhiq.zhaopin.com/moment/73399615    
https://zq.zhaopin.com/moment/73399612    
https://zq-mobile.zhaopin.com/moment/73399612    
https://zhiq.zhaopin.com/moment/73399612    
https://zq.zhaopin.com/moment/73399604    
https://zq-mobile.zhaopin.com/moment/73399604    
https://zhiq.zhaopin.com/moment/73399604    
https://zq.zhaopin.com/moment/73399599    
https://zq-mobile.zhaopin.com/moment/73399599    
https://zhiq.zhaopin.com/moment/73399599    
https://zq.zhaopin.com/moment/73399593

使用建议

  1. 保持简洁:Stream链不宜过长,过长时应考虑拆分或重构

  2. 避免副作用:不要在lambda表达式中修改外部状态

  3. 优先使用方法引用:使代码更简洁(如 String::length代替 s -> s.length())

  4. 注意性能:小数据集可能传统循环更快,大数据集并行流更有优势

  5. 合理使用并行流:数据量小或操作简单时,并行可能更慢

总结

Stream是Java 8带来的革命性特性,它让集合操作变得更加:

  • 声明式:关注"做什么"而非"怎么做"

  • 可组合:操作可以像管道一样连接起来

  • 可并行:轻松利用多核处理器提升性能

  • 简洁优雅:代码更简洁易读

掌握Stream不仅能让你的代码更加现代化,还能提高开发效率和程序性能。从今天开始,尝试用Stream重构你的集合处理代码吧!


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69960915/viewspace-3101295/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2025-11-12

  • 博文量
    20
  • 访问量
    22025