You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用Java Stream通过匹配name字段更新对象列表的dob属性?

用Java Stream实现通过name匹配更新对象的dob属性

当然可以用Java Stream搞定这个需求!这种方式比传统双重循环清爽多了,而且借助Map的快速查找特性,效率也会更高。下面给你捋清楚实现思路和代码示例:

核心思路

  • 先把对象B的列表转换成以name为键、dob为值的Map,这样后续匹配时能直接通过键快速查找,避免双重循环带来的O(n*m)时间复杂度
  • 遍历对象A的列表,利用Stream的操作匹配Map中的对应值,完成A的dob属性更新

代码实现

首先定义实体类

先简单定义A和B两个实体类(实际开发中记得补全构造器、getter/setter和toString方法):

import java.time.LocalDate;

class A {
    private String name;
    private int age;
    private LocalDate dob;

    public A(String name, int age) {
        this.name = name;
        this.age = age;
        this.dob = null;
    }

    // Getter和Setter
    public String getName() { return name; }
    public int getAge() { return age; }
    public LocalDate getDob() { return dob; }
    public void setDob(LocalDate dob) { this.dob = dob; }

    @Override
    public String toString() {
        return "A{name='" + name + "', age=" + age + ", dob=" + dob + '}';
    }
}

class B {
    private String name;
    private LocalDate dob;

    public B(String name, LocalDate dob) {
        this.name = name;
        this.dob = dob;
    }

    // Getter
    public String getName() { return name; }
    public LocalDate getDob() { return dob; }
}

Stream实现逻辑

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class UpdateDobWithStream {
    public static void main(String[] args) {
        // 初始化测试数据:A列表所有dob为null
        List<A> listA = List.of(
                new A("Alice", 25),
                new A("Bob", 30),
                new A("Charlie", 28)
        );

        // B列表所有dob有有效值
        List<B> listB = List.of(
                new B("Alice", LocalDate.of(1998, 5, 15)),
                new B("Bob", LocalDate.of(1993, 10, 20))
                // Charlie在B列表中无匹配,dob保持null
        );

        // 把B列表转成name -> dob的Map
        // 注意:如果B列表有重复name,toMap会抛异常,需添加合并逻辑(比如保留最后一个值)
        Map<String, LocalDate> nameToDobMap = listB.stream()
                .collect(Collectors.toMap(
                        B::getName,
                        B::getDob,
                        (existingDob, newDob) -> newDob // 重复name时保留新值
                ));

        // 方式1:直接修改原A对象的dob属性
        listA.stream()
                .forEach(a -> {
                    LocalDate matchedDob = nameToDobMap.get(a.getName());
                    if (matchedDob != null) {
                        a.setDob(matchedDob);
                    }
                });

        // 方式2:生成新的A对象列表(不修改原列表,适合不可变对象场景)
        /*
        List<A> updatedListA = listA.stream()
                .map(a -> {
                    A newA = new A(a.getName(), a.getAge());
                    newA.setDob(nameToDobMap.get(a.getName()));
                    return newA;
                })
                .collect(Collectors.toList());
        */

        // 打印验证结果
        listA.forEach(System.out::println);
    }
}

关键细节说明

  • Map转换的优势:将B列表转为Map后,查找操作的时间复杂度从O(n)降至O(1),当列表数据量较大时,效率提升非常明显
  • 重复name的处理:如果B列表中存在相同name的对象,默认的Collectors.toMap会抛出IllegalStateException,这时候需要传入第三个参数指定合并规则(比如示例中保留最后出现的dob值)
  • 修改原对象vs生成新对象:示例中提供了两种方式,如果你不想修改原A列表的对象,可以选择map生成新列表的方式,更符合函数式编程的不可变原则

内容的提问来源于stack exchange,提问作者user_mes

火山引擎 最新活动