You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Java中同number的SampleObject对象合并为一个?

合并相同Number的SampleObject对象问题解决

问题场景

现有SampleObject类,包含number、valueOne、valueTwo、valueThree属性:

  • 每个对象的number非空
  • 每个对象仅一个value字段(valueOne/valueTwo/valueThree)非空
    AnotherClass类包含该对象的列表,需要将列表中相同number的SampleObject合并为一个对象,最终生成以number为键、合并后对象为值的Map。

示例

原对象列表:

  • Sample1(number:"1", valueOne="1", valueTwo=null, valueThree=null)
  • Sample2(number:"1", valueOne=null, valueTwo="2", valueThree=null)
  • Sample3(number:"1", valueOne=null, valueTwo=null, valueThree="3")
  • Sample4(number:"2", valueOne="5", valueTwo=null, valueThree=null)

期望合并结果:

  • Sample1Merged(number:"1", valueOne="1", valueTwo="2", valueThree="3")
  • Sample4(number:"2", valueOne="5", valueTwo=null, valueThree=null)

现有问题

当前代码使用forEach直接向Map中put对象,遇到相同number时会直接覆盖已有对象,无法实现属性合并:

final Map<String, SampleObject> mapOfMergedSamples = new LinkedHashMap<>();

anotherClass.getSampleObjects().stream()
    .sorted(Comparator.comparing(SampleObject::getNumber))
    .forEach(s -> mapOfMergedSamples.put(s.getNumber(), new SampleObject(Stream.of(s.getValueOne(), s.getValueTwo())
        .filter(Objects::nonNull)
        .collect(Collectors.joining()), s.getValueThree()))
    );
    
return mapOfMergedSamples;

解决方案

使用Stream.collect()结合Collectors.toMap(),通过指定合并函数处理重复键的对象,实现属性合并而非覆盖。

代码实现

final Map<String, SampleObject> mapOfMergedSamples = anotherClass.getSampleObjects()
    .stream()
    .collect(Collectors.toMap(
        // 提取number作为Map的键
        SampleObject::getNumber,
        // 初始值为当前对象
        sample -> sample,
        // 合并相同number的两个对象
        (existingSample, newSample) -> {
            // 逐个合并value属性:优先保留已有对象的非空值,否则取新对象的值
            String mergedValueOne = existingSample.getValueOne() != null ? existingSample.getValueOne() : newSample.getValueOne();
            String mergedValueTwo = existingSample.getValueTwo() != null ? existingSample.getValueTwo() : newSample.getValueTwo();
            String mergedValueThree = existingSample.getValueThree() != null ? existingSample.getValueThree() : newSample.getValueThree();
            
            // 返回合并后的新SampleObject对象(需匹配你的类构造方法参数)
            return new SampleObject(existingSample.getNumber(), mergedValueOne, mergedValueTwo, mergedValueThree);
        },
        // 指定用LinkedHashMap保持原列表顺序(可选,和你原代码一致)
        LinkedHashMap::new
    ));

return mapOfMergedSamples;

关键逻辑说明

  1. Collectors.toMap的合并函数:
    当遇到相同number的对象时,该函数会将已有对象(existingSample)和新对象(newSample)的非空value属性进行合并。由于题目中每个原对象仅一个非空value,因此直接取两边的非空值即可完成合并。
  2. 保持顺序:
    最后一个参数LinkedHashMap::new确保合并后的Map和原列表的顺序一致,和你原代码的LinkedHashMap逻辑匹配,可根据需求选择是否保留。
  3. 构造方法适配:
    注意代码中的new SampleObject(...)需要匹配你实际的SampleObject类构造方法参数,确保参数顺序和数量正确。

简化写法(可选)

如果你的SampleObject类支持Builder模式,合并逻辑可以更简洁:

(existing, newSample) -> new SampleObject.Builder()
    .number(existing.getNumber())
    .valueOne(Optional.ofNullable(existing.getValueOne()).orElse(newSample.getValueOne()))
    .valueTwo(Optional.ofNullable(existing.getValueTwo()).orElse(newSample.getValueTwo()))
    .valueThree(Optional.ofNullable(existing.getValueThree()).orElse(newSample.getValueThree()))
    .build()

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 23:20:40