Java基础知识18--hutool中BeanUtil工具类的常用方法;Java Bean间属性值的复制(BeanUtils使用)
1. hutool中BeanUtil工具类的常用方法
构造两个实体类:
Employee.java
package com.ttbank.flep.test; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import java.util.Date; /** * @Author lucky * @Date 2022/6/28 17:48 */ @Data @NoArgsConstructor @AllArgsConstructor @Accessors public class Employee { public static Integer a; private Integer id; private String employeeName; // 变量名为 employeeName private Integer gender; private Date birth; private Integer salary; // 设置为 Integer 类型 }
User.java
package com.ttbank.flep.test; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import java.util.Date; /** * @Author lucky * @Date 2022/6/28 17:47 */ @Data @NoArgsConstructor @AllArgsConstructor @Accessors public class User { public static int a = 2020; private Integer id; private String userName; // 变量名为 userName private Integer gender; // 0女,1男 private Date birth; private Double salary; // 设置为 Double 类型 }
pom依赖:
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>4.1.19</version> </dependency>
1.1 beanToMap方法与mapToBean方法
Map<String, Object> beanToMap(Object bean, boolean isToUnderlineCase, boolean ignoreNullValue)
功能:将一个对象转换成Map<String, Object>,属性名为key,值为value,只支持实例变量。
参数解释:bean待转对象,isToUnderlineCase是否转下划线,ignoreNullValue是否忽略空值。
返回值:返回转换后的Map对象。
public static void main(String[] args) { User user = new User(1001,"张三",0,null,8000.0); Map<String, Object> map1 = BeanUtil.beanToMap(user, false, false); // 不转下划线,不忽略空值 Map<String, Object> map2 = BeanUtil.beanToMap(user, true, true); // 转下划线,忽略空值 System.out.println(map1); // {id=1001, userName=张三, gender=0, birth=null, salary=8000.0} System.out.println(map2); // {id=1001, user_name=张三, gender=0, salary=8000.0} User user1 = BeanUtil.mapToBean(map1, User.class, false); System.out.println(user1.toString()); //User(id=1001, userName=张三, gender=0, birth=null, salary=8000.0) }
1.2 copyProperties方法
最实用的方法,比如远程获取几个属性,然后返回给VO,用这个方法避免了一个个同名参数的复制
public static void copyProperties(Object source, Object target, CopyOptions copyOptions)
- 功能:复制属性,类似克隆,但比clone()方法更强大。
- 参数解释:source待克隆对象,target克隆后返回对象类型,ignoreProperties哪些属性忽略不克隆。
- 返回值:复制属性完成后,返回复制后的对象。
CopyOptions 配置项:
CopyOptions 参数提供一些 BeanUtils.copyProperties 注入属性的选项。
(1) ignoreNullValue 是否忽略空值,当源对象的值为 null 时,true: 忽略而不注入此值,false: 注入 null
(2) ignoreProperties 忽略的属性列表,设置一个属性列表,不拷贝这些属性值
(3) ignoreError 是否忽略字段注入错误
(4) 可以通过 CopyOptions.create () 方法创建一个默认的配置项,通过 setXXX 方法设置每个配置项。
public static void main(String[] args) { User user = new User(1001,"张三",1,DateUtil.parse("1997-12-08"), 8000.0); Employee employee = new Employee(); BeanUtil.copyProperties(user, employee, CopyOptions.create().setIgnoreNullValue(true)); // 将user对象,克隆成Employee类型返回,忽略属性id System.out.println(employee);//Employee(id=1001, employeeName=null, gender=1, birth=1997-12-08 00:00:00, salary=8000) }
2.Java Bean间属性值的复制(BeanUtils使用)
需求:两个对象中有相同类型相同名称的属性,把一个对象中的属性值复制到另一个对象。
注意:方法1和方法2实现的效果是一样的;
方法1:
maven依赖:
<dependency> <groupId>org.springframework</groupId> <artifactId>org.springframework.beans</artifactId> <version>3.1.3.RELEASE</version> </dependency>
public static void copyProperties(Object source, Object target)
该方法只能对一个bean中普通属性字段进行copy,如果这个bean中有其他的bean,即bean中bean,就需要将其值取出,单独对这个子bean进行copy,然后set进父bean,这种copy如果在bean层次少的时候还无所谓,如果在bean的层次比较深的时候,就会发现很是繁琐了
将a拷贝到b(只拷贝相同的属性值)
BeanUtils.copyProperties(a, b);
- b中的存在的属性,a中一定要有,但是a中可以有多余的属性;
- a中与b中相同的属性都会被替换,不管是否有值;
- a、 b中的属性要名字相同,才能被赋值,不然的话需要手动赋值;
- Spring的BeanUtils的CopyProperties方法需要对应的属性有getter和setter方法;
- 如果存在属性完全相同的内部类,但是不是同一个内部类,即分别属于各自的内部类,则spring会认为属性不同,不会copy;
- spring和apache的copy属性的方法源和目的参数的位置正好相反,所以导包和调用的时候都要注意一下。
方法2:
实体类:
Customer类
/** * @Author lucky * @Date 2022/1/4 10:28 */ @Slf4j @Builder @Data public class Customer { private String name; private int age; private String gender; private Map<String,String> params; private Map<String,String> heads; }
User类:
@Data @Builder @Slf4j @AllArgsConstructor @NoArgsConstructor public class User { private String name; private int age; private String gender; private Map<String,String> params; }
工具类:
/** * @Author lucky * @Date 2022/1/4 10:14 */ @Slf4j public class BeanCopyUtils { public static <T> void beanCopyProperties(T src, T dest){ Map<String,Object> properties=new HashMap<>(); Arrays.stream(src.getClass().getDeclaredFields()).forEach((field -> { try { field.setAccessible(true); properties.put(field.getName(), field.get(src)); } catch (IllegalAccessException e) { //log.error("",e ); } })); populateBean(dest,dest.getClass(),properties); populateBean(dest,dest.getClass().getSuperclass(),properties); } private static <T> void populateBean(T bean,Class clazz,Map<String,Object> properties){ Arrays.stream(clazz.getDeclaredFields()).forEach((field -> { try { field.setAccessible(true); //如果非空,覆盖原有值;如果为空,则不覆盖原有值 if(properties.get(field.getName())!=null){ field.set(bean,properties.get(field.getName())); } } catch (IllegalAccessException e) { //log.error("",e); } })); } public static void main(String[] args) { Map<String,String> params=new HashMap<>(); params.put("userInfo","ttbank 2021"); Customer customer = Customer.builder().age(26).gender("man").params(params).build(); //01 使用自己创建的工具类 User user=new User(); user.setName("lucky"); beanCopyProperties(customer, user); System.out.println(user); params.put("userInfo","ttbank 2022"); System.out.println(user); System.out.println(customer); //02 使用工具类BeanUtils User user2=new User(); BeanUtils.copyProperties(customer,user2); System.out.println(user2); } }
控制台输出:
User(name=lucky, age=26, gender=man, params={userInfo=ttbank 2021}) User(name=lucky, age=26, gender=man, params={userInfo=ttbank 2022}) Customer(name=null, age=26, gender=man, params={userInfo=ttbank 2022}, heads=null) User(name=null, age=26, gender=man, params={userInfo=ttbank 2022})
参考文献:
https://blog.csdn.net/qq_37276508/article/details/102366097
https://blog.csdn.net/str_tang/article/details/108034911---hutool使用 --推荐