如何利用Java的Stream API提高代码的简洁度和效率?

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:掘金/C站/腾讯云/阿里云/华为云/51CTO(全网同号);欢迎大家常来逛逛,互相学习。

今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

作为一个已经在Java开发职场中摸爬滚打了数年的码农,我深知代码的简洁性和效率对于维护一个大型项目有多么重要。在这些年来的项目开发中,我不断优化和重构代码,尤其是在处理集合和流数据时,我逐渐转向了Java 8引入的Stream API。这个作为jdk8的 新特性,不仅让代码更简洁,还让开发过程更加高效。

你可能会问,Stream API到底能带来什么好处呢?是不是所有的场景都能用Stream来提高效率呢?今天,我就结合我多年的开发经验,带你深入了解如何使用Stream API优化代码,提高效率,减少冗余。

1. 什么是Stream API?

Stream API是Java 8引入的一项新特性,它提供了一种声明性、函数式的编程方式来处理集合(例如ListSet)等数据。它允许我们通过流水线式的操作(类似Unix管道)来处理数据流,而不需要编写大量的循环和条件判断,从而使代码更加简洁、可读。

简单来说,Stream API让你能够使用链式操作 来处理数据,比如过滤、排序、映射等,而这些操作都可以通过Stream流式进行,避免了传统的繁琐处理。Stream API的最大特点就是它支持惰性计算并行化处理,从而在性能上也能够提供优化。

2. 使用Stream API的好处

通过Stream API,我们可以实现以下几点好处:

  • 简洁性:代码的可读性提高,减少了显式的循环和条件判断。
  • 函数式编程:使用流式操作,代码更加简洁、优雅。
  • 惰性计算:Stream流的操作是惰性求值的,只有在最终操作时才会触发数据的计算。
  • 并行处理 :Stream API使得并行处理变得简单,可以通过parallelStream()轻松地启用并行处理,提升性能。

3. 常见的Stream API操作

3.1 创建Stream

Stream可以通过多种方式创建,常见的几种方法有:

  • 通过集合创建Stream:
java 复制代码
List<String> list = Arrays.asList("a", "b", "c", "d");
Stream<String> stream = list.stream(); // 创建Stream
  • 通过数组创建Stream:
java 复制代码
String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);
  • 通过Stream.of()方法创建Stream:
java 复制代码
Stream<String> stream = Stream.of("a", "b", "c", "d");

3.2 常见的Stream操作

Stream API的操作分为两类:中间操作终止操作

3.2.1 中间操作(Intermediate Operations)

这些操作会返回一个新的Stream,允许我们继续进行链式调用。中间操作是惰性求值的,只有在终止操作执行时才会计算。

  • filter():过滤数据,返回满足条件的元素。
java 复制代码
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: 喵手
 * @date: 2025-08-15 17:05
 */
public class Test1 {
    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);  // 输出:[2, 4]
    }
}

具体展示界面截图如下:

  • map():对数据进行映射,转换成不同的形式。
java 复制代码
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: 喵手
 * @date: 2025-08-15 17:08
 * @desc:
 */
public class Test2 {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("Java", "Vue", "Python");
        List<String> upperWords = words.stream()
                .map(String::toUpperCase)  // 转换为大写
                .collect(Collectors.toList());
        System.out.println(upperWords);  // 输出:[JAVA, VUE, PYTHON]
    }
}

具体展示界面截图如下:

  • distinct():去重,返回一个去重后的Stream。
java 复制代码
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
List<Integer> distinctNumbers = numbers.stream()
                                       .distinct()  // 去重
                                       .collect(Collectors.toList());
System.out.println(distinctNumbers);  // 输出:[1, 2, 3, 4, 5]
  • sorted():排序。
java 复制代码
List<Integer> numbers = Arrays.asList(5, 3, 4, 1, 2);
List<Integer> sortedNumbers = numbers.stream()
                                     .sorted()  // 排序
                                     .collect(Collectors.toList());
System.out.println(sortedNumbers);  // 输出:[1, 2, 3, 4, 5]
  • limit():限制流的长度。
java 复制代码
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
List<Integer> limitedNumbers = numbers.stream()
                                      .limit(3)  // 取前3个元素
                                      .collect(Collectors.toList());
System.out.println(limitedNumbers);  // 输出:[1, 2, 3]

3.2.2 终止操作(Terminal Operations)

终止操作会触发流的计算并返回结果。常见的终止操作有:

  • forEach():对Stream中的每个元素执行操作。
java 复制代码
List<String> words = Arrays.asList("apple", "banana", "cherry");
words.stream()
     .forEach(word -> System.out.println(word.toUpperCase()));
// 输出:
// APPLE
// BANANA
// CHERRY
  • collect():将Stream转换为其他形式,如集合或数组。
java 复制代码
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> collectedNumbers = numbers.stream()
                                       .collect(Collectors.toList());  // 转换为List
System.out.println(collectedNumbers);  // 输出:[1, 2, 3, 4, 5]
  • reduce():对Stream中的元素进行归约操作,通常用于求和、求积等。
java 复制代码
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
                 .reduce(0, (a, b) -> a + b);  // 求和
System.out.println(sum);  // 输出:15
  • count():返回Stream中的元素个数。
java 复制代码
List<String> words = Arrays.asList("apple", "banana", "cherry");
long count = words.stream()
                  .count();  // 获取元素个数
System.out.println(count);  // 输出:3
  • anyMatch():判断是否有任何元素符合条件。
java 复制代码
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean hasEven = numbers.stream()
                         .anyMatch(n -> n % 2 == 0);  // 是否有偶数
System.out.println(hasEven);  // 输出:true

4. 使用Stream API提高效率和简洁度

4.1 处理大数据集合

在处理大数据时,Stream API提供了更高效的方式,特别是在需要进行复杂转换、过滤和聚合操作时。通过Stream,你可以将操作链式连接,而不是手动编写多个for循环嵌套,从而使代码更简洁。

java 复制代码
/**
 * @author: 喵手
 * @date: 2025-08-15 17:17
 */
public class Test3 {
    public static void main(String[] args) {

        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);

        //传统方式:
        int sum = 0;
        for (int number : numbers) {
            if (number % 2 == 0) {
                sum += number;
            }
        }
        System.out.println(sum);  // 输出:12

        // 使用Stream API
        int sumStream = numbers.stream()
                .filter(n -> n % 2 == 0)
                .mapToInt(Integer::intValue)
                .sum();
        System.out.println(sumStream);  // 输出:12
    }
}

通过Stream API,我们可以将过滤、转换、聚合等操作合并为一个链式调用,而不需要显式地写循环和条件判断。这样代码更简洁,也能提高可读性。

具体展示界面截图如下:

4.2 并行化处理

Stream API还支持并行流(parallelStream()),它能够自动将任务分解成多个子任务并行执行,从而提高处理效率。在处理大量数据时,使用并行流能够有效提升性能,尤其是在多核处理器的机器上。

java 复制代码
import java.util.Arrays;
import java.util.List;

/**
 * @author: 喵手
 * @date: 2025-08-15 17:17
 */
public class Test4 {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // 顺序流
        long startTime = System.nanoTime();
        long sum = numbers.stream()
                .mapToInt(Integer::intValue)
                .sum();
        long endTime = System.nanoTime();
        System.out.println("顺序流耗时: " + (endTime - startTime));

        // 并行流
        startTime = System.nanoTime();
        long sumParallel = numbers.parallelStream()
                .mapToInt(Integer::intValue)
                .sum();
        endTime = System.nanoTime();
        System.out.println("并行流耗时: " + (endTime - startTime));
    }
}

通过并行流,你可以让计算在多个CPU核心之间分配任务,提高程序的执行效率。

具体展示界面截图如下:

5. 总结

Java的Stream API极大地提升了我们在处理集合、数组等数据时的效率和简洁度。通过链式调用和惰性计算,Stream使得代码更加简洁和具有声明性,特别是在数据转换、过滤、聚合等场景下,能显著减少代码的冗余。而且,通过parallelStream(),我们可以轻松实现并行化处理,提升处理效率。

当然,Stream API也并非没有缺点。虽然它非常适用于处理集合类型的数据,但对于一些性能要求极高的场景,过度使用Stream仍然可能带来性能上的损耗。因此,在使用Stream时,要根据具体的业务需求做出合适的选择。

总之,Stream API为我们提供了一个更加函数式、简洁、并行的编程方式,如果能合理使用,它一定能在我们的项目中发挥巨大的作用。

... ...

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

... ...

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。

⭐️若有疑问,就请评论留言告诉我叭。


版权声明:本文由作者原创,转载请注明出处,谢谢支持!

相关推荐
教练、我想打篮球8 分钟前
117 javaweb servlet+jsp 项目中修改了 数据库连接配置, 却怎么都不生效
java·servlet·jdbc·jsp
你不是我我10 分钟前
【Java 开发日记】我们来说一说 Redis IO 多路复用模型
java·开发语言·redis
SadSunset12 分钟前
(13)复杂查询
java·笔记·架构·mybatis
浩瀚地学13 分钟前
【Java】ArrayList
java·开发语言·经验分享·笔记
阿杰同学21 分钟前
Java 设计模式 面试题及答案整理,最新面试题
java·开发语言·设计模式
这样の我21 分钟前
java 模拟chrome指纹 处理tls extension顺序
java·开发语言·chrome
vx_bisheyuange22 分钟前
基于SpringBoot的游戏交易系统
spring boot·后端·游戏·毕业设计
Genevieve_xiao26 分钟前
【数据结构与算法】【xjtuse】面向考纲学习(下)
java·数据结构·学习·算法
4311媒体网28 分钟前
php和c++哪个更好学?C++难学吗?
java·c++·php
毕设源码-朱学姐33 分钟前
【开题答辩全过程】以 基于SpringBoot的流行音乐网站的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端