巧用Java 8 Stream流简化集合操作

简介: 本文详解Java 8 Stream API如何简化集合操作:通过filter筛选、map转换、collect收集等声明式方法,一行代码替代冗长for循环。以成年用户处理为例,对比传统写法,突出Stream在可读性、简洁性与可维护性上的显著优势。(239字)

在Java开发中,集合处理是日常高频操作。传统的for循环遍历、筛选、转换不仅代码冗余,可读性也差。Java 8引入的Stream流(Stream API)能以声明式的方式处理集合,让代码更简洁、易维护。本文通过简单示例,带你快速上手Stream流的核心用法。

场景说明

假设我们有一个用户列表,需要完成三个常见操作:

  1. 筛选出年龄大于18岁的成年用户;
  2. 提取这些用户的姓名并拼接成字符串;
  3. 统计成年用户的数量。

传统循环实现

先看传统for循环的写法,感受一下冗余的代码:

import java.util.ArrayList;
import java.util.List;

// 定义用户实体类
class User {
   
    private String name;
    private int age;

    // 构造方法
    public User(String name, int age) {
   
        this.name = name;
        this.age = age;
    }

    // getter方法
    public String getName() {
   
        return name;
    }

    public int getAge() {
   
        return age;
    }
}

public class StreamDemo {
   
    public static void main(String[] args) {
   
        // 初始化用户列表
        List<User> userList = new ArrayList<>();
        userList.add(new User("张三", 20));
        userList.add(new User("李四", 17));
        userList.add(new User("王五", 25));
        userList.add(new User("赵六", 16));

        // 传统方式:筛选成年用户、提取姓名、统计数量
        List<String> adultNames = new ArrayList<>();
        int adultCount = 0;
        for (User user : userList) {
   
            if (user.getAge() > 18) {
    // 筛选条件
                adultNames.add(user.getName()); // 提取姓名
                adultCount++; // 统计数量
            }
        }

        // 拼接姓名
        String nameStr = String.join(", ", adultNames);
        System.out.println("成年用户姓名:" + nameStr);
        System.out.println("成年用户数量:" + adultCount);
    }
}

Stream流实现

用Stream流重构后,代码更简洁,逻辑更清晰:

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

// 复用上面的User实体类
public class StreamOptDemo {
   
    public static void main(String[] args) {
   
        // 初始化用户列表
        List<User> userList = new ArrayList<>();
        userList.add(new User("张三", 20));
        userList.add(new User("李四", 17));
        userList.add(new User("王五", 25));
        userList.add(new User("赵六", 16));

        // Stream流方式:一站式完成筛选、转换、统计
        // 1. 筛选成年用户并提取姓名
        List<String> adultNames = userList.stream()
                .filter(user -> user.getAge() > 18) // 筛选条件:年龄>18
                .map(User::getName) // 提取姓名(方法引用)
                .collect(Collectors.toList()); // 转换为List

        // 2. 统计成年用户数量
        long adultCount = userList.stream()
                .filter(user -> user.getAge() > 18)
                .count(); // 直接统计数量

        // 3. 拼接姓名
        String nameStr = adultNames.stream().collect(Collectors.joining(", "));

        System.out.println("成年用户姓名:" + nameStr);
        System.out.println("成年用户数量:" + adultCount);
    }
}

代码解释

  1. stream():将集合转换为Stream流,开启流式操作;
  2. filter():接收Lambda表达式作为筛选条件,只保留符合条件的元素;
  3. map():对元素进行转换,这里通过User::getName(方法引用)提取用户姓名;
  4. collect():将流转换为指定集合(如Collectors.toList())或拼接字符串(Collectors.joining());
  5. count():统计流中元素的数量,返回long类型。

运行结果

两种写法的运行结果一致:

成年用户姓名:张三, 王五
成年用户数量:2

总结

  1. Stream流以声明式编程替代传统命令式循环,代码更简洁、可读性更高;
  2. 核心方法filter()(筛选)、map()(转换)、collect()(收集)是Stream流的高频用法;
  3. Stream流支持链式调用,可一站式完成多步集合操作,减少中间变量的定义。

Stream流不仅能简化集合操作,还支持并行流(parallelStream())提升大数据量处理效率,是Java 8及以上版本必备的核心技能。

相关文章
|
5月前
|
存储 缓存 Java
Java 对象内存布局:从堆内存储到伪共享优化的底层真相
Java对象内存布局是JVM核心基础:含对象头(Mark Word+Klass指针)、实例数据(字段重排序优化)和对齐填充(8字节对齐)。它直接影响内存占用、GC效率、锁升级与伪共享性能。掌握此机制,是深入理解并发优化(如@Contended)、指针压缩及高性能编程的必经之路。(239字)
558 111
|
6月前
|
SQL 缓存 算法
Java 内存模型与 volatile:并发底层的轻量级同步核心
`volatile` 是JMM核心轻量级同步关键字,通过内存屏障禁用重排、借助MESI协议保障可见性,精准解决可见性与有序性(不保证原子性),是DCL单例、状态标志等场景的基石,堪称高效并发编程的“轻量级钥匙”。(239字)
386 7
|
5月前
|
编译器 Linux C语言
整数提升与寻常算术转换——90%算术bug的隐形根源
C语言算术bug的根源常被误认为“编译器玄学”,实则源于C标准强制规定的**整数提升与寻常算术转换**规则。本文深入剖析其底层逻辑、典型陷阱(如符号扩展、有/无符号混用)及避坑实践,助你根治违背直觉的隐形bug。(239字)
|
5月前
|
JavaScript 前端开发 Java
闭包:被误解最深的 JavaScript 特性
闭包本质是JS保留作用域上下文的能力,非语法而是引擎机制。它支撑私有变量封装、模块化与防抖/节流等高级模式。内存泄漏主因是未及时解除引用,而非闭包本身。理解闭包,方懂JS作用域与生命周期精髓。(239字)
|
5月前
|
人工智能 安全 编译器
C语言的「隐形时序契约」:序列点、副作用与求值顺序终极拆解
本文深入解析C语言中极易被忽视的“序列点”机制,揭示Debug/Release模式差异、跨平台结果不一致等玄学bug的根源——未定义行为(UB)。从副作用定义出发,系统梳理7类标准序列点,剖析4大高频陷阱(如`i=i++ + ++i`),并提供6条安全编码铁律,助你写出稳定、可移植的C代码。(239字)
427 11
|
5月前
|
缓存 编译器 程序员
C语言深度解析:restrict关键字——编译器性能优化的终极钥匙
C99的`restrict`关键字是C语言性能优化的“终极钥匙”:它向编译器承诺指针独占访问内存,彻底解决同类型指针别名问题,解锁循环向量化、寄存器缓存等激进优化。滥用致未定义行为,善用则性能飙升数倍——这才是真正高阶C程序员的必修课。(239字)
|
5月前
|
Java API
Java MethodHandle:超越反射的轻量化方法调用底层引擎
Java 7引入的MethodHandle是JVM级动态调用机制,相比反射:仅一次权限校验、强类型绑定、零装箱开销、支持方法适配与invokedynamic。性能达反射3–10倍,是Lambda、动态代理及现代框架的底层引擎。(239字)
289 6
|
5月前
|
存储 C语言 内存技术
C语言深度解析:大小端字节序——多字节数据的底层存储规则
大小端指CPU对多字节数据在内存中的存放顺序:大端高字节存低地址,小端反之。x86/ARM默认小端,网络字节序统一为大端。跨平台、网络通信、二进制协议开发中必须显式处理字节序转换,否则数据解析必错。
1094 138