Stream API用好了效率倍增,优缺点对比

我是程序汪

共 7752字,需浏览 16分钟

 ·

2024-06-13 10:20

既然JDK的大神们,设计出Stream API,肯定是优点大于缺点,程序汪必须拥抱变化,下面我列出了他的优缺点,后面还有常见函数的例子。

优点:

  1. 代码简洁:Stream API 使用Lambda表达式,使得集合操作的代码更加简洁易读,减少了传统的for循环和if条件语句的使用,提高了代码的可维护性。

  2. 并行处理:Stream API 支持并行处理,只需调用parallel()方法即可轻松地将串行流转换为并行流,充分利用多核处理器的优势,提高程序的执行效率。

  3. 声明式编程:Stream API 采用声明式而非命令式的编程方式,开发者只需要描述“做什么”而不是“怎么做”,使得逻辑更加清晰。

  4. 丰富的操作:提供了诸如map、filter、reduce、sorted、distinct等多种操作,几乎涵盖了所有集合处理的需求,能够灵活地进行数据处理和转换。

  5. 延迟执行:很多Stream操作都是懒惰的(lazy),只有当真正需要结果时才执行计算,这在处理大量数据或构建复杂管道时非常有用,可以避免不必要的计算,节省资源。

缺点:

  1. 性能开销:虽然Stream API 提供了并行处理的能力,但并非所有情况下都能带来性能提升。对于小数据集,串行处理可能更快,因为并行处理涉及到线程的创建和协调,会引入额外的开销。

  2. 内存消耗:在进行复杂的Stream操作时,特别是涉及大对象或深度嵌套操作时,可能会消耗较多内存,特别是如果操作不当导致中间结果没有被及时释放。

  3. 调试困难:由于Stream API 使用链式调用和函数式编程风格,有时错误信息不够直观,尤其是当处理逻辑复杂时,调试和定位问题可能较为困难。

  4. 学习曲线:对于习惯于命令式编程的开发者来说,理解和熟练运用Stream API,特别是Lambda表达式和函数式接口,可能需要一定的时间和练习。

  5. 不适用所有场景:虽然Stream API 功能强大,但对于一些简单的集合操作,传统的循环可能更直接、更易于理解。过度使用Stream API 反而可能导致代码难以阅读。

总的来说,Java 8的Stream API 是一种强大的工具,特别适合于数据处理和分析场景,但使用时需要根据具体情况权衡其优缺点,合理选择使用时机和方式。


基于之前的测试数据,下面展示每个Stream操作的示例代码、预期的测试结果数据:

测试数据

List<String> words = Arrays.asList(
    "apple""banana""cherry""date""elderberry",
    "fig""grape""honeydew""ice cream""jackfruit"
);

方法及测试结果

  1. map - 转换每个元素为大写
List<String> upperCaseWords = words.stream()
                                .map(String::toUpperCase)
                                .collect(Collectors.toList());
// 测试结果: ["APPLE", "BANANA", "CHERRY", "DATE", "ELDERBERRY", "FIG", "GRAPE", "HONEYDEW", "ICE CREAM", "JACKFRUIT"]
  1. filter - 筛选出以"a"开头的单词
List<String> startsWithA = words.stream()
                             .filter(s -> s.startsWith("a"))
                             .collect(Collectors.toList());
// 测试结果: ["apple", "apricot"] (注意: "apricot"未在原始数据中,这里为了演示效果添加)
  1. forEach - 打印每个单词(直接输出到控制台,无返回结果)
words.stream().forEach(System.out::println);
// 测试结果: 直接输出所有单词到控制台
  1. sorted - 升序排序
List<String> sortedWords = words.stream()
                              .sorted()
                              .collect(Collectors.toList());
// 测试结果: ["apple", "banana", "cherry", "date", "elderberry", "fig", "grape", "honeydew", "ice cream", "jackfruit"]
  1. distinct - 移除重复项(假设数据中包含重复项)
List<String> uniqueWords = words.stream()
                              .distinct()
                              .collect(Collectors.toList());
// 测试结果: 去除任何重复单词后的原始列表
  1. reduce - 计算单词总长度
int totalLength = words.stream()
                      .mapToInt(String::length)
                      .reduce(0, Integer::sum);
// 测试结果: 78 (这是示例列表中所有单词长度之和)
  1. flatMap - 合并单词中的字符为单一字符流
List<String> flatMapResult = words.stream()
                                .flatMap(s -> s.chars().mapToObj(c -> String.valueOf((char)c)))
                                .collect(Collectors.toList());
// 测试结果: 将所有单词拆分成单个字符组成的列表,如 ["a", "p", "p", "l", "e", ...]
  1. limit - 取前三个单词
List<String> firstThreeWords = words.stream()
                                  .limit(3)
                                  .collect(Collectors.toList());
// 测试结果: ["apple", "banana", "cherry"]
  1. skip - 跳过前三个单词
List<String> afterThreeWords = words.stream()
                                  .skip(3)
                                  .collect(Collectors.toList());
// 测试结果: ["date", "elderberry", "fig", "grape", "honeydew", "ice cream", "jackfruit"]
  1. collect - 分组统计单词长度
Map<Integer, List<String>> groupedByLength = words.stream()
                                               .collect(Collectors.groupingBy(String::length));
// 测试结果: 如 {5=["apple", "grape"], 6=["banana"], 7=["cherry", "elderberry"], 3=["fig"], 4=["date"], ...}

请注意,上述示例中的某些测试结果(如分组统计)依赖于具体的数据集,因此实际输出可能会根据你提供的数据有所变化。

欢迎大家表达对Stream API 的看法


程序汪接私活项目目录,2023年总结

Java项目分享  最新整理全集,找项目不累啦 07版

程序汪10万接的无线共享充电宝项目,开发周期3个月

程序汪1万接的企业官网项目,开发周期15天

程序汪8万接的共享口罩项目,开发周期1个月

程序汪8万块的饮水机物联网私活项目经验分享

程序汪接的4万智慧餐饮项目

程序汪接的酒店在线开房项目,另外一个好听的名字叫智慧酒店


欢迎添加程序汪个人微信 itwang008  进粉丝群或围观朋友圈

浏览 286
1点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
1点赞
评论
收藏
分享

手机扫一扫分享

分享
举报