Java实现对象复制合并 Java 对象合并 java对象复制 null值不复制, 目标对象有值 不覆盖

        Java实现对象复制合并 Java 对象合并 java对象复制 null值不复制, 目标对象有值 不覆盖

一、概述

        近期的开发中,遇到一个需求, 有2个Java对象,需要合并成一个对象,然后去更新数据。 把2个对象合并为一个对象,规则是:

      • 源对象: 属性为NULL ,则不覆盖 目标对象。
      • 目标对象:属性不为NULL,则不需要覆盖。

        实现思路: 初始的计划是,用反射的方式,获取2个对象的全部字段,然后逐个遍历,去逐一判断,若 源对象 字段为NULL,则忽略 ; 若 目标对象 属性不为NULL,则忽略。 伪代码,大致如下:


UserParam source = src;
UserParam target = dest;
for (Field s : source.getClass().getDeclaredFields()) {
    s.setAccessible(true);
    final Object o = s.get(source);
    if(Objects.isNull(o)){
        continue;
    }
    final Field t = target.getClass().getDeclaredField(s.getName());
    t.setAccessible(true);
    final Object o1 = t.get(target);
    if(Objects.nonNull(o1)){
        continue;
    }
    // 开始属性合并操作
    t.set(target,o);
}

        经过一番研究发现,hutool工具中,已经有对应的 BeanUtil 可以实现上述操作,且功能更强大,下面的案例中,将以 hutool BeanUtil 方式,实现Java 对象合并。

二、代码实现

        1、有一个普通的Java Bean : UserParam

public class UserParam {

   private Integer id ;
   
   private String name ;
   
   private String addr ;

   private BigDecimal bigDecimal ; //测试传参空字符时的取值情况
   
     // ignore getter , setter   , toString()
}

        2、hutool 依赖pom.xml


<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
   <groupId>cn.hutool</groupId>
   <artifactId>hutool-all</artifactId>
   <version>5.7.18</version>
</dependency>

        3、测试代码如下

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;

@Test
public void testFix() throws Exception{
    final UserParam src = new UserParam();
    src.setId(123);
    src.setAddr("北京市");
    src.setBigDecimal(BigDecimal.ZERO);

    final UserParam dest = new UserParam();
    dest.setName("二狗子");
    dest.setBigDecimal(BigDecimal.TEN);

    final CopyOptions copyOptions = CopyOptions.create();
    copyOptions.setOverride(false);
    copyOptions.setIgnoreNullValue(true);
    BeanUtil.copyProperties(src,dest, copyOptions);
    System.out.println(dest);
}

        4、输出结果

src : UserParam [id=123, name=null, addr=北京市, bigDecimal=0]
dest : UserParam [id=123, name=二狗子, addr=北京市, bigDecimal=10]

三、总结

        1、使用 hutool的BeanUtil 即可实现对象的合并,具体报名是: cn.hutool.core.bean.BeanUtil ,已经有对应的工具类实现,无需再重复编码。

        

        2、可以关注hutool的CopyOptions , 有更多的对象合并选项可以配置,摘录如下:

protected Class<?> editable;
/**
 * 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null
 */
protected boolean ignoreNullValue;
/**
 * 属性过滤器,断言通过的属性才会被复制
 */
protected BiPredicate<Field, Object> propertiesFilter;
/**
 * 忽略的目标对象中属性列表,设置一个属性列表,不拷贝这些属性值
 */
protected String[] ignoreProperties;
/**
 * 是否忽略字段注入错误
 */
protected boolean ignoreError;
/**
 * 是否忽略字段大小写
 */
protected boolean ignoreCase;
/**
 * 拷贝属性的字段映射,用于不同的属性之前拷贝做对应表用
 */
protected Map<String, String> fieldMapping;
/**
 * 反向映射表,自动生成用于反向查找
 */
private Map<String, String> reversedFieldMapping;
/**
 * 字段属性编辑器,用于自定义属性转换规则,例如驼峰转下划线等
 */
protected Editor<String> fieldNameEditor;
/**
 * 字段属性值编辑器,用于自定义属性值转换规则,例如null转""等
 */
protected BiFunction<String, Object, Object> fieldValueEditor;
/**
 * 是否支持transient关键字修饰和@Transient注解,如果支持,被修饰的字段或方法对应的字段将被忽略。
 */
protected boolean transientSupport = true;
/**
 * 是否覆盖目标值,如果不覆盖,会先读取目标对象的值,非{@code null}则写,否则忽略。如果覆盖,则不判断直接写
 */
protected boolean override = true;

        

        看了那么多,不如去亲自动手试一试咯~

参考资料:

java Introspector内省和Reflect反射学习、联系和区别 

Java反射 getFields和 getDeclaredFields 方法的区别 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值