当前位置: 首页 > article >正文

23、深入理解 Java Stream:高效处理数据的利器

在 Java 编程的领域中,随着业务逻辑日益复杂,数据处理的效率与代码的简洁性成为开发者关注的重点。Java 8 引入的 Stream API,犹如一股清新的风,为开发者带来了一种全新的数据处理方式。它不仅简化了代码结构,还大幅提升了数据处理的效率与灵活性。

一、揭开 Java Stream 的神秘面纱

Stream 代表着一个支持顺序和并行聚合操作的元素序列。它与传统的集合不同,Stream 并不存储数据,而是在数据的源(如集合、数组)上进行一系列操作。Stream 的核心特点在于其延迟执行机制,中间操作(如过滤、映射)不会立即执行,只有当终端操作(如计数、遍历)被调用时,整个操作流水线才会被触发,这种特性使得 Stream 在处理数据时能进行优化,避免不必要的计算开销。

1. Stream 的创建方式

Stream 的创建极为灵活,可以从多种数据源构建。

  • 从集合创建:集合是 Java 中常用的数据结构,通过stream()方法,能轻松将集合转换为 Stream。例如:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class StreamFromCollection {
    public static void main(String[] args) {
        List<Integer> numberList = new ArrayList<>();
        numberList.add(1);
        numberList.add(2);
        numberList.add(3);
        Stream<Integer> streamFromList = numberList.stream();
    }
}

  • 从数组创建:数组作为另一种基础数据结构,同样能快速转变为 Stream。利用Arrays.stream()方法即可达成:
import java.util.Arrays;
import java.util.stream.Stream;

public class StreamFromArray {
    public static void main(String[] args) {
        int[] numberArray = {1, 2, 3};
        Stream<int[]> streamFromArray = Stream.of(numberArray);
        // 或者使用专门针对基本类型数组的方法
        IntStream intStream = Arrays.stream(numberArray);
    }
}

  • 生成无限 Stream:Stream 还支持创建无限序列,通过Stream.iterate()Stream.generate()方法实现。例如,生成一个从 0 开始,每次递增 1 的无限序列:
import java.util.stream.Stream;

public class InfiniteStream {
    public static void main(String[] args) {
        Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 1);
        // 通常需要限制长度,比如只取前10个
        infiniteStream.limit(10).forEach(System.out::println);
    }
}

二、Stream 的操作盛宴

Stream API 提供了丰富多样的操作,这些操作可分为中间操作和终端操作。

1. 中间操作

中间操作会返回一个新的 Stream,以便在其上继续进行链式操作。

  • filter(过滤):筛选出符合特定条件的元素。比如,从一组整数中筛选出偶数:
import java.util.Arrays;
import java.util.List;

public class FilterExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        numbers.stream()
              .filter(n -> n % 2 == 0)
              .forEach(System.out::println);
    }
}

  • map(映射):对 Stream 中的每个元素应用一个函数,将其转换为另一种形式。例如,将整数列表中的每个数平方:
import java.util.Arrays;
import java.util.List;

public class MapExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        numbers.stream()
              .map(n -> n * n)
              .forEach(System.out::println);
    }
}

  • distinct(去重):去除 Stream 中的重复元素。假设一个包含重复元素的列表:
import java.util.Arrays;
import java.util.List;

public class DistinctExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 1, 2, 2, 3);
        numbers.stream()
              .distinct()
              .forEach(System.out::println);
    }
}

  • sorted(排序):对 Stream 中的元素进行排序。既可以使用自然排序(针对实现了Comparable接口的类型),也可以使用自定义比较器:
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class SortedExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5);
        // 自然排序
        numbers.stream()
              .sorted()
              .forEach(System.out::println);
        // 自定义比较器,按降序排序
        numbers.stream()
              .sorted(Comparator.reverseOrder())
              .forEach(System.out::println);
    }
}

2. 终端操作

终端操作会触发 Stream 的执行,并返回一个结果或产生副作用。

  • forEach(遍历):对 Stream 中的每个元素执行一个操作。例如,打印列表中的所有元素:
import java.util.Arrays;
import java.util.List;

public class ForEachExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3);
        numbers.stream()
              .forEach(System.out::println);
    }
}

  • collect(收集):将 Stream 中的元素收集到一个集合中,如ListSetMap。例如,将 Stream 中的偶数收集到一个List中:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class CollectExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        List<Integer> evenNumbers = numbers.stream()
                                          .filter(n -> n % 2 == 0)
                                          .collect(Collectors.toList());
        System.out.println(evenNumbers);
    }
}

  • reduce(归约):通过一个累积函数将 Stream 中的元素归约为一个值。比如计算整数列表的总和:
import java.util.Arrays;
import java.util.List;

public class ReduceExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        int sum = numbers.stream()
                        .reduce(0, (a, b) -> a + b);
        System.out.println(sum);
    }
}

  • count(计数):统计 Stream 中元素的数量。例如,统计列表中偶数的个数:
import java.util.Arrays;
import java.util.List;

public class CountExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        long count = numbers.stream()
                           .filter(n -> n % 2 == 0)
                           .count();
        System.out.println(count);
    }
}

三、Stream 带来的显著优势

  1. 代码简洁性:Stream 通过链式调用的方式,将复杂的数据处理逻辑以一种简洁明了的方式表达出来,避免了冗长的循环和繁琐的临时变量声明。
  2. 可读性提升:Stream 的操作更接近自然语言的表达,使得代码的意图更加清晰,易于理解和维护。
  3. 并行处理能力:只需简单地切换为并行流(parallelStream()),Stream 就能充分利用多核处理器的优势,自动并行执行操作,极大地提升了大数据集的处理效率。

四、总结

Java Stream 为 Java 开发者带来了一种全新的数据处理范式,它以简洁的语法、强大的功能和高效的性能,成为处理数据的得力工具。无论是日常开发中的小数据处理,还是面对大数据量的复杂业务场景,Stream 都能发挥其独特的优势。随着对 Stream 理解的深入,开发者能够编写出更优雅、高效的 Java 代码,提升开发效率与代码质量。


http://www.kler.cn/a/536572.html

相关文章:

  • git push解决 error src refspec master does not match anyerror
  • 离线安装Appium Server
  • Word List 2
  • RabbitMQ 从入门到精通:从工作模式到集群部署实战(三)
  • 解锁反序列化漏洞:从原理到防护的安全指南
  • langchain教程-3.OutputParser/输出解析
  • 什么是高光谱成像相机?
  • .NET周刊【1月第3期 2025-01-19】
  • 网站改HTTPS方法
  • YOLOv11-ultralytics-8.3.67部分代码阅读笔记-downloads.py
  • PHP云调查考试问卷系统小程序
  • C++开发(软件开发)常见面试题
  • 【QT】控件 -- 多元素类 | 容器类 | 布局类
  • 日志级别修改不慎引发的一场CPU灾难
  • Elasticsearch 高级技巧
  • 基于机器学习时序库pmdarima实现时序预测
  • 使用 `WITH` 子句优化复杂 SQL 查询
  • 6 maven工具的使用、maven项目中使用日志
  • RISC-V芯片与扩展医疗影像处理边缘设备编程探析
  • SQL Server 数据库迁移到 MySQL 的完整指南
  • BCrypt加密密码和md5加密哪个更好一点///jwt和rsa有什么区别//为什么spring中经常要用个r类
  • 优惠券平台(十一):布隆过滤器、缓存空值、分布式组合的双重判定锁解决缓存穿透问题
  • 区块链技术:Facebook 重塑社交媒体信任的新篇章
  • Copilot量化指标参数及其方法
  • 37构造回文字符串问题-青训营刷题
  • 蓝桥杯小白打卡第四天