Java8 Stream中对集合数据进行快速匹配和赋值的代码示例

 更新时间:2023年06月29日 11:48:07   作者:左羊  
这篇文章主要介绍了Java8 Stream中如何对集合数据进行快速匹配和赋值,文中通过代码示例为大家介绍的非常详细,具有一定的参考价值,需要的朋友可以参考下

开幕先看代码

List<Hero> heroes = StreamListDemo01.heroValues();
List<Salarys> salarysValues = StreamListDemo01.salarysValues();
for (Hero hero : heroes) {
     if (salarysValues.size()>0) {
       for (Salarys salarysValue : salarysValues) {
         if (hero.getId()==salarysValue.getId()) {
               hero.setSalary(salarysValue.getSalary());
               break;
          }
         hero.setSalary(0.0F);
         }
    }else{
      hero.setSalary(0.0F);
        }
   }

需求是这个样子的

小编是要为一个 Hero 集合中的每个对象,赋予一个匹配的 Salarys 对象中的 salary 值。具体实现方式为遍历 Hero 集合,对于每一个 Hero 对象,遍历 Salarys 集合,只有当 Hero 对象的 ID 与 Salarys 对象的 ID 匹配时,才将 Salarys 对象的 salary 值赋值给 Hero 的 salary 属性。如果 Hero 的 ID 没有匹配成功,则将 Hero 的 salary 属性设置为 0.0F。如果 Salarys 集合为空,则将 Hero 的 salary 属性设置为 0.0F。

虽然通过嵌套for搞定了,但是我想把这玩意搞成Java8 Stream写法的!接下让我们开始看逐步拆解吧。

思路概述

  • 将heroes转换为Stream对象;
  • 使用peek操作设置所有hero的初始salary为0;
  • 对heroes进行forEach操作,对于每个hero,将salarysValues转换为Stream对象;
  • 使用filter操作筛选出符合条件的salary(即id匹配);
  • 使用findFirst操作获取第一个匹配结果(如果有的话);
  • 如果有匹配结果,则使用ifPresent操作将salary的值赋给该hero的salary属性。若无匹配结果,则salary仍为初始值0。

步骤详解

  • 将heroes转换为Stream对象

将heroes集合对象转换为Stream对象,可以使用以下方式:

heroes.stream()
  • 使用peek操作设置所有hero的初始salary为0

使用peek方法来实现操作了,peek方法会遍历集合中的每一个元素,可以对每个元素进行操作并返回一个 Stream 对象。

.peek(hero -> hero.setSalary(0.0F))
  • 对heroes进行forEach操作,对于每个hero,将salarysValues转换为Stream对象

在forEach方法中对每个hero进行操作,对于每个hero,需要将另一个集合 salarysValues 转换为 Stream 对象,可以使用以下操作:

.forEach(hero -> {
    salarysValues.stream()
  • 使用filter操作筛选出符合条件的salary(即id匹配)

对于 salarysValues 集合中元素的筛选,需要通过filter操作进行筛选。filter方法返回一个Stream,由于我们只需要一个结果,因此使用findFirst方法获取第一个结果。

.filter(salary -> hero.getId() == salary.getId())

该代码会对salarysValues集合中的每个元素进行比较操作,将符合条件的元素返回作为一个新的Stream,只有符合条件的元素才会继续执行下面的操作。使用lambda表达式的方式,将当前hero的id和salarysValues集合中的id进行比较,如果相同,则返回 true。

  • 使用findFirst操作获取第一个匹配结果(如果有的话)

使用findFirst方法获取第一个匹配的结果,如果有分配的Salary,则第一个匹配结果应该是分配到该Hero的Salary。findFirst方法返回一个Optional对象,Optional封装了要返回对象可能为空的情况。

.findFirst()
  • 如果有匹配结果,则使用ifPresent操作将salary的值赋给该hero的salary属性。若无匹配结果,则salary仍为初始值0。

使用ifPresent方法,如果结果不为空(存在匹配结果),就将结果设置给该Hero的Salary,如果不存在匹配结果,则该Hero的Salary属性值不被改变,即为初始值0。

.ifPresent(salary -> hero.setSalary(salary.getSalary()));
hero.setSalary(0.0F); // 设置Hero的薪水属性初始值为0

完整stream代码示例:

heroes.stream()
    .peek(hero -> hero.setSalary(0.0F)) // 设置所有hero的初始salary为0
    .forEach(hero -> {
        salarysValues.stream()
            .filter(salary -> hero.getId() == salary.getId()) // 筛选出符合条件的salary
            .findFirst() // 获取第一个匹配结果(如果存在)
            .ifPresent(salary -> hero.setSalary(salary.getSalary())); // 将匹配到的salary的值赋给hero
        hero.setSalary(0.0F); // 如果不存在匹配结果,设置薪水初始值为0
    });

完整示例代码

public class StreamListDemo01 {
    private static List<Hero> heroValues(){
        List<Hero> heroes = new ArrayList<>();
        for (int i = 1; i < 10; i++) {
            Hero hero = new Hero();
            hero.setId(i);
            hero.setName("张三"+i);
            heroes.add(hero);
        }
        return heroes;
    }
    private static List<Salarys> salarysValues(){
        List<Salarys> salarysList = new ArrayList<>();
        for (int i = 1; i < 5; i++) {
            Salarys salarys = new Salarys();
            salarys.setId(i);
            salarys.setSalary(1.4F+i);
            salarysList.add(salarys);
        }
        return salarysList;
    }
    public static void main(String[] args) {
        List<Hero> heroes = StreamListDemo01.heroValues();
        List<Salarys> salarysValues = StreamListDemo01.salarysValues();
        for (Hero hero : heroes) {
            if (salarysValues.size()>0) {
                for (Salarys salarysValue : salarysValues) {
                    if (hero.getId()==salarysValue.getId()) {
                        hero.setSalary(salarysValue.getSalary());
                        break;
                    }
                    hero.setSalary(0.0F);
                }
            }else{
                hero.setSalary(0.0F);
            }
        }
        heroes.stream()
                .peek(hero -> hero.setSalary(0.0F)) // 设置所有hero的初始salary为0
                .forEach(hero -> {
                    salarysValues.stream()
                            .filter(salary -> hero.getId() == salary.getId())
                            .findFirst()
                            .ifPresent(salary -> hero.setSalary(salary.getSalary())); // 将匹配到的salary的值赋给hero
                });
                    System.out.println(heroes);
    }
}
class Hero{
    private String Name;
    private int Id;
    private Float Salary;
    public String getName() {
        return Name;
    }
    public void setName(String name) {
        Name = name;
    }
    public int getId() {
        return Id;
    }
    public void setId(int id) {
        Id = id;
    }
    public Float getSalary() {
        return Salary;
    }
    public void setSalary(Float salary) {
        Salary = salary;
    }
    @Override
    public String toString() {
        return "Hero{" +
                "Name='" + Name + '\'' +
                ", Id=" + Id +
                ", Salary=" + Salary +
                '}';
    }
}
class Salarys{
    private int Id;
    private Float Salary;
    public int getId() {
        return Id;
    }
    public void setId(int id) {
        Id = id;
    }
    public Float getSalary() {
        return Salary;
    }
    public void setSalary(Float salary) {
        Salary = salary;
    }
    @Override
    public String toString() {
        return "Salarys{" +
                "Id=" + Id +
                ", Salary=" + Salary +
                '}';
    }
}

参考文献:

1. Java 8 Stream API官方文档:https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
2. 《Java 8 Stream Tutorial》:https://www.baeldung.com/java-8-streams-introduction

到此这篇关于Java8 Stream中对集合数据进行快速匹配和赋值的代码示例的文章就介绍到这了,更多相关Java8 Stream对数据匹配赋值内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Tomcat ClassLoader打破双亲委派源码解析

    Tomcat ClassLoader打破双亲委派源码解析

    这篇文章主要为大家介绍了Tomcat ClassLoader打破双亲委派源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 解决pageHelper分页失效以及如何配置问题

    解决pageHelper分页失效以及如何配置问题

    这篇文章主要介绍了解决pageHelper分页失效以及如何配置问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • Git设置和取消代理的方法

    Git设置和取消代理的方法

    今天小编就为大家分享一篇关于Git设置和取消代理的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • Java双向链表倒置功能实现过程解析

    Java双向链表倒置功能实现过程解析

    这篇文章主要介绍了Java双向链表倒置功能实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • Java中几种常用加密算法盘点

    Java中几种常用加密算法盘点

    随着互联网的发展,信息安全问题日益受到重视,加密算法在保证信息安全传输方面发挥着重要作用,本文将简要盘点几种常用的Java加密算法,介绍它们的基本原理、特点及应用情况,以帮助读者全面了解当前加密算法的发展状况,需要的朋友可以参考下
    2023-11-11
  • Spring注解Autowired的底层实现原理详解

    Spring注解Autowired的底层实现原理详解

    从当前springboot的火热程度来看,java config的应用是越来越广泛了,在使用java config的过程当中,我们不可避免的会有各种各样的注解打交道,其中,我们使用最多的注解应该就是@Autowired注解了。本文就来聊聊Autowired的底层实现原理
    2022-10-10
  • IntelliJ IDEA 小技巧之Bookmark(书签)的使用

    IntelliJ IDEA 小技巧之Bookmark(书签)的使用

    这篇文章主要介绍了IntelliJ IDEA 小技巧之Bookmark(书签)的使用,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • Java 简化正则表达式的使用

    Java 简化正则表达式的使用

    本篇文章主要介绍了Java 简化正则表达式使用的相关知识,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-04-04
  • maven如何利用springboot的配置文件进行多个环境的打包

    maven如何利用springboot的配置文件进行多个环境的打包

    这篇文章主要介绍了maven如何利用springboot的配置文件进行多个环境的打包,在Spring Boot中多环境配置文件名需要满足application-{profiles.active}.properties的格式,其中{profiles.active}对应你的环境标识,本文给大家详细讲解,需要的朋友可以参考下
    2023-02-02
  • 实例讲解MyBatis如何防止SQL注入

    实例讲解MyBatis如何防止SQL注入

    这篇文章通过实例代码介绍MyBatis如何防止SQL注入,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-12-12

最新评论