磨磨蹭蹭写了一个月的东西,总算是写出成果来了。记录一下流程,加深记忆。
要求:在一个List里,有多个成员,这些成员的某个属性相同,但是其他属性可能为空,如果把这些成员都统合起来,可以凑成一个完整的成员。
简单来讲就是合并对象啦。
先安排一个实体类(Person),用来做载体,引入lombok插件(依赖),方便偷懒:
package com.alltobenice.personalproject1.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
//实体类:Person 测试用的载体;
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(exclude = {"age","gender"})
public class Person {
private String name;
private int age;
private String gender;
private String birthArea;
private Boolean isMarry;
}
接下来就是构建合并对象用的工具类了
package com.alltobenice.personalproject1.util;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName: mergeObject
* @Description: 对象合并
* @Author: allToBeNice
* @Since: 2021/6/30 8:47
*/
public class MergeObjectUtil {
//需要传进来一个List.size()大于1的集合,还可以优化这个方法,少加一个判断;
public static <T> List<T> mergeObjectList(List<T> targetList){
List<T> mergedList = new ArrayList<>();
Object target;
T targetObject1 = targetList.get(0);
T targetObject2 = targetList.get(1);
target = mergeObject(targetObject1, targetObject2);
if(targetList.size() >= 3){
for(int i = 2; i < targetList.size(); i++){
T targetObjectX = targetList.get(i);
target = mergeObject(target,targetObjectX);
}
}
mergedList.add((T)target);
return mergedList;
}
//合并两个对象;
public static Object mergeObject(Object firstBean,Object secondBean){
Field[] firstBeanFields = firstBean.getClass().getDeclaredFields();
Field[] secondBeanFields = secondBean.getClass().getDeclaredFields();
for(int i = 0; i < firstBeanFields.length; i++){
Field firstBeanField = firstBeanFields[i];
Field secondBeanField = secondBeanFields[i];
Type firstBeanFieldGenericType = firstBeanField.getGenericType(); //属性类型
firstBeanField.setAccessible(true);
secondBeanField.setAccessible(true);
try{
//判定属性的类型--是否是String
if(firstBeanFieldGenericType.toString()
.equals("class java.lang.String")){
//如果first对象的当前属性是空的,则second对象的对应属性填充first对象的值
if((firstBeanField.get(firstBean) == null)){
firstBeanField.set(firstBean,secondBeanField.get(secondBean));
}
// else if(secondBeanField.get(secondBean) == null){
// secondBeanField.set(secondBean,firstBeanField.get(firstBean));
// }
//判定属性的类型--是否是int。
}else if ("int".equals(firstBeanFieldGenericType.getTypeName()) || firstBeanFieldGenericType.toString()
.equals("class java.lang.Integer")){
//如果first对象的当前属性比second对象的对应属性要小,则填充second的值
if(firstBeanField.getInt(firstBean) - secondBeanField.getInt(secondBean) < 0){
firstBeanField.set(firstBean,secondBeanField.get(secondBean));
}
//判定属性的类型--是否是date
}else if(firstBeanFieldGenericType.toString()
.equals("class java.util.Date")){
if((firstBeanField.get(firstBean) == null)){
firstBeanField.set(firstBean,secondBeanField.get(secondBean));
}
//判定属性的类型--是否是Boolean (默认为false,如果有true,就设置为true
}else if(firstBeanFieldGenericType.toString()
.equals("class java.lang.Boolean")){
if(!(secondBeanField.get(secondBean) == null) && (Boolean)secondBeanField.get(secondBean) ){
firstBeanField.set(firstBean,secondBeanField.get(secondBean));
}
}
//判定其他类型--例如 : 引用类型 等;
} catch (Exception e){
e.printStackTrace();
}
}
return firstBean;
}
}
最后,写个测试类测试一下这个合并对象的功能。
@Test
public void mergeObjectTest(){
Person person1 = new Person("小刚",22,null,null,true);
Person person2 = new Person("小刚",0,null,"C省",true);
Person person3 = new Person("小刚",0,"M",null,true);
Person person =(Person)MergeObjectUtil.mergeObject(person1, person2);
Person person4 =(Person)MergeObjectUtil.mergeObject(person, person3);
System.out.println(person4.toString());
}
//输出结果:Person(name=小刚, age=22, gender=M, birthArea=C省, isMarry=true)
再整一个集合类型的,合并看看。
@Test
public void mergeObjectListTest(){
List<Person> persons = new ArrayList<>();
Person person1 = new Person("小明",22,null,null,true);
Person person2 = new Person("小红",0,null,"C省",true);
Person person3 = new Person("小刚",32,null,null,null);
Person person4 = new Person("小刚",0,null,null,true);
Person person5 = new Person("小刚",0,"M","C省",null);
persons.add(person1);
persons.add(person2);
persons.add(person3);
persons.add(person4);
persons.add(person5);
//按名称分组;
Map<String, List<Person>> personMap = persons.stream().collect(Collectors.groupingBy(Person::getName));
Set<Map.Entry<String, List<Person>>> personEntries = personMap.entrySet();
//循环取出每个List,判定List的size大小;
for(Map.Entry<String, List<Person>> entry : personEntries){
String key = entry.getKey();
System.out.println(" key => " + key);
List<Person> value = entry.getValue();
if(value.size() > 1){
List<Person> mergedPersonList = MergeObjectUtil.mergeObjectList(value);
System.out.println("mergedValue => " + mergedPersonList.toString());
}else{
System.out.println("value => " + value.toString());
}
System.out.println("________________________");
}
}
//输出结果: key => 小刚
//mergedValue => [Person(name=小刚, age=32, gender=M, birthArea=C省, isMarry=true)]
//________________________
// key => 小明
//value => [Person(name=小明, age=22, gender=null, birthArea=null, isMarry=true)]
//________________________
// key => 小红
//value => [Person(name=小红, age=0, gender=null, birthArea=C省, isMarry=true)]
//________________________
以上。
我知道还存在更好的,可以实现当前需求的方式,如果你知道的话,请一定告诉我。谢谢。