Java  比较两个对象的不同之处(old, new)   包含 bean 对象下的 list, Map , bean 的细节

 

package com.icil.pinpal.test1;

import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.junit.Test;
import org.springframework.util.Assert;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

/***************************
 *<pre>
 * @Project Name : base-case-test-service
 * @Package      : com.icil.pinpal.test1
 * @File Name    : BaseTest 
 * @Author       : Sea
 * @Mail         : lshan523@163.com
 * @Date         : 2022/11/21 16:43
 * @Purpose      :
 * @History      :
 *</pre>
 ***************************/
public class BaseTest {

    //    ##########################   准备bean  ##############################
/*    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    static public class BaseDO {
        private  String name;
        private  Integer age;
        private List<String> likes;
        private  List<Child> childrens;
        private Map mymap;
        private Child childx;

        public BaseDO(String name, Integer age, List<String> likes, List<Child> childrens) {
            this.name = name;
            this.age = age;
            this.likes = likes;
            this.childrens = childrens;
        }
    }


    @AllArgsConstructor
    @NoArgsConstructor
    @Data
   static public class Child {
        private  String name;
        private  Integer age;
    }*/


//    ##########################  比较 方法 ##############################


    private static final List<Class<?>> WRAPPER = Arrays.asList(Byte.class, Short.class,
            Integer.class, Long.class, Float.class, Double.class, Character.class,
            Boolean.class, String.class);

    /**
     * compare the bean fields value if different
     * @param source obj
     * @param target obj
     * @return {key:[old,new]}
     * @throws Exception
     */
    public static JSONObject getDiff(Object source, Object target) throws Exception {
        JSONObject diff =new JSONObject();
        Assert.notNull(source, "Source must not be null");
        Assert.notNull(target, "Target must not be null");
        Class<?> compareObj = target.getClass();
        Field[] fields = compareObj.getDeclaredFields();
        for (Field field : fields) {
            PropertyDescriptor pd = new PropertyDescriptor(field.getName(), compareObj);
            Method getMethod = pd.getReadMethod();
            Object o1 = getMethod.invoke(source);
            Object o2 = getMethod.invoke(target);
            String s1 = o1 == null ? "" : o1.toString();
            String s2 = o2 == null ? "" : o2.toString();
            if (!s1.equals(s2))
            {
                //############### 处理list,对比list 的不同  ##################
                if(o1 instanceof Collection){
                    Collection<Object> o11 = (Collection) o1;
                    Collection<Object> o22 = (Collection) o2;
                    Collection common = o11.stream().filter(o -> o22.contains(o)).collect(Collectors.toList());
                    o11.removeAll(common);
                    o22.removeAll(common);
                    diff.put(field.getName(), Arrays.asList(o11,o22));
                }
                else if(o1 instanceof Map)
                {  // #########  处理 map 对比map 的不同 #########
                    Map<String,Object> O11 = (Map) o1;
                    Map<String,Object> O22 = (Map) o2;
                    // o1  diff 02
                    JSONObject o1diffo2 = new JSONObject();
                    for(Map.Entry<String,Object> oo1 : O11.entrySet())
                    {
                        String key = oo1.getKey();
                        O11.getOrDefault(key,"");
                        if(!O11.getOrDefault(key,"").equals(O22.getOrDefault(key,""))){
                            o1diffo2.put(key,oo1.getValue());
                        }
                    }
                    // o2  diff 01
                    JSONObject o2diffo1 = new JSONObject();
                    for(Map.Entry<String,Object> oo2 : O22.entrySet())
                    {
                        String key = oo2.getKey();
                        O11.getOrDefault(key,"");
                        if(!O22.getOrDefault(key,"").equals(O11.getOrDefault(key,""))){
                            o1diffo1.put(key,oo2.getValue());
                        }
                    }
                    diff.put(field.getName(), Arrays.asList(o1diffo2,o2diffo1));
                }
                // ################## 如果为 bean 对象 (不是基本类型,不是list  也不是map) ##################
                else if((!o1.getClass().isPrimitive() && !WRAPPER.contains(o1.getClass())) && !(o1 instanceof Collection) && !(o1 instanceof Map))
                {
                    diff.put(field.getName(), getDiff(o1,o2));
                }
                else
                {
                    diff.put(field.getName(), Arrays.asList(s1,s2));
                }
            };
        }
        return diff;
    }





    @Test
    public void testNam1e() throws Exception
    {
        // 数据一
        List<String> likes = new ArrayList<String>(){
              {add("basketball");
                add("football");}
        };

        List<Child> childrens = new ArrayList<Child>(){{
            add(new Child("aa",12));
            add(new Child("bb",15));
        }};
        BaseDO sea = new BaseDO("sea", 30, likes, childrens);
        sea.setMymap(new HashMap() {{put("xx22","1"); put("xx1","2"); put("xx2","12"); put("xxxx2","12");}});
        sea.setChildx(new Child("xx",12));


        // 数据二
        List<String> likes1 = new ArrayList<String>(){
            {add("Table tennis");
                add("football");}
        };

        List<Child> childrens1 = new ArrayList<Child>(){{
            add(new Child("aa",12));
            add(new Child("cc",12));
            add(new Child("bb",16));
        }};
        BaseDO sea1 = new BaseDO("sea", 31, likes1, childrens1);
        sea1.setMymap(new HashMap() {{put("xx","1"); put("xx1","2"); put("xx2","12");}});
        sea1.setChildx(new Child("xxx",12));
        //比较
        JSONObject diff = getDiff(sea, sea1);
        System.err.println(diff);

    }


}

测试结果:

{"childrens":[[{"age":15,"name":"bb"}],[{"age":12,"name":"cc"},{"age":16,"name":"bb"}]],"childx":{"name":["xx","xxx"]},"mymap":[{"xxxx2":"12","xx22":"1"},{"xx":"1"}],"age":["30","31"],"likes":[["basketball"],["Table tennis"]]}

 

posted on 2022-11-21 19:25  lshan  阅读(894)  评论(0编辑  收藏  举报