如何递归的合并两个对象

99 阅读1分钟

本文介绍了一种递归合并两个同类型对象的方法,合并属性的同时,会递归的比较子属性,同时会对子属性进行合并,直到已经不再有子属性为止。当然如果这个对象比较复杂,一定要小心,有可能会出现把栈空间挤爆的情况,会抛出StackOverflowError异常

/**
 * @author huangji
 * @version 1.0
 **/
public class MergeUtil {
    //调用此方法来进行合并,外部调用为Object mergedObj = merge(source,target);
    public static Object merge(Object sourceBean, Object targetBean) throws IllegalAccessException {
        //判断传参条件
        if (sourceBean == null) {
            return targetBean;
        }
        if (targetBean == null) {
            return sourceBean;
        }
        //通过反射获取属性数组
        Field[] originalFields = sourceBean.getClass().getDeclaredFields();
        Field[] targetFields = targetBean.getClass().getDeclaredFields();


        for (int i = 0; i < originalFields.length; i++) {
            // final类型的不需要进行值拷贝
            if (Modifier.isFinal(originalFields[i].getModifiers())) {
                continue;
            }
            /** 
             *  java对于某些属性不允许进行访问,会直接抛出异常,
             *  因此需要捕获异常,避免程序终止
             **/
            try {
                originalFields[i].setAccessible(true);
                targetFields[i].setAccessible(true);
            } catch (Exception e) {
                continue;
            }
            Object originalValue = originalFields[i].get(sourceBean);
            Object targetValue = targetFields[i].get(targetBean);
            if (originalValue != null) {
                if (targetValue == null) {
                    //这里进行实际的属性复制操作
                    targetFields[i].set(targetBean, originalValue);
                    //对于List类型,有可能List非空,但List中的子元素需要合并,故需要单独判断
                } else if (List.class.isAssignableFrom(originalFields[i].getType())) {
                    List<?> sourceList = (List<?>) originalFields[i].get(sourceBean);
                    List<?> targetList = (List<?>) targetFields[i].get(targetBean);
                    mergeList(sourceList, targetList);
                } else {
                    merge(originalValue, targetValue);
                }
            }
        }

        return targetBean;
    }

    public static void mergeList(List<?> sourceList, List<?> targetList) throws IllegalAccessException {
        if (sourceList.size() == targetList.size()) {
            for (int i = 0; i < sourceList.size(); i++) {
                merge(sourceList.get(i), targetList.get(i));
            }
        }
    }
}