比较两个对象中的字段,并在Java中更新其中一个

比较两个对象中的字段,并在Java中更新其中一个,java,Java,我遇到了一个问题,即用用户所做的任何更改来更新现有数据 例如,我有一个公司对象,如下所示 public class Company { private String id; private String name; private String url; //Getter and setter..... } 现在我有一个公司实例,数据如下 Company company = new Company(); company.setId("id12345678

我遇到了一个问题,即用用户所做的任何更改来更新现有数据

例如,我有一个公司对象,如下所示

public class Company {

    private String id;

    private String name;

    private String url;

    //Getter and setter.....
}
现在我有一个公司实例,数据如下

Company company = new Company();
company.setId("id12345678");
company.setName("company Old Name");
company.setUrl("company Old Url");
现在用户已经创建了另一个公司实例,只需更新现有公司的
名称
url

Company newCompany = new Company();
newCompany.setId("id12345678");
newCompany.setName("company New Name");
newCompany.setUrl("company New Url");
可以看到,
Company
的新实例与旧实例具有相同的
Id
,但具有不同的
name
url

是否有任何实用工具/库可以简单地找到这两个对象之间的所有差异,并将更改应用到
公司
实例?(真的不想编写代码来手动比较每个字段)

差不多

company = AwesomeLibraryUtils.compareAndApplyDifferences(company, newCompany);
在此之后,
company
实例保持相同的id,但具有来自
newcommany
实例的
name
url
的所有新值


谢谢。

您应该重写
equals()
方法。之后,您将能够检查条件
company.equals(newCompany)

著名的IDE支持自动生成equals方法。例如,IDEA将其生成为:

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Company company = (Company) o;

    if (id != null ? !id.equals(company.id) : company.id != null) return false;
    if (name != null ? !name.equals(company.name) : company.name != null) return false;
    return !(url != null ? !url.equals(company.url) : company.url != null);

}

使用reflect查找公司和新公司中getter和setter的所有结果

public static void compareAndApplyDifferences(Object o1, Object o2) {
    if(!o1.getClass().equals(o2.getClass())) {
        return;
    }
    // check if the result of getters in o1 and o2 are different
    boolean isDiff = false;
    Class<? extends Object> c1 = o1.getClass();
    Class<? extends Object> c2 = o2.getClass();
    Method[] methods1 = c1.getMethods();
    Method[] methods2 = c2.getMethods();
    Map<String, Object> hm = new HashMap<String, Object>();
    for (Method method2 : methods2) {
        if (isGetter(method2)) {
            try {
                Object getterResult = method2.invoke(o2);
                hm.put(method2.getName().substring(3), getterResult);
            } catch (IllegalAccessException e) {
            } catch (IllegalArgumentException e) {
            } catch (InvocationTargetException e) {
            }
        }
    }
    for (Method method1 : methods1) {
        if (isGetter(method1)) {
            try {
                String getterResult = (String) method1.invoke(o1);
                if (!hm.containsValue(getterResult)) {
                    isDiff = true;
                    break;
                }
            } catch (IllegalAccessException e) {
            } catch (IllegalArgumentException e) {
            } catch (InvocationTargetException e) {
            }
        }
    }

    if (isDiff) {
        // set the values in o1 as the values in o2
        for (Method method1 : methods1) {
            if (isSetter(method1)) {
                try {
                    method1.invoke(o1, hm.get(method1.getName().substring(3)));
                } catch (IllegalAccessException e) {
                } catch (IllegalArgumentException e) {
                } catch (InvocationTargetException e) {
                }
            }
        }
    } else {
        return;
    }
}

private static boolean isGetter(Method method) {
    if (!method.getName().startsWith("get"))
        return false;
    if (method.getParameterTypes().length != 0)
        return false;
    if (void.class.equals(method.getReturnType()))
        return false;
    return true;
}

private static boolean isSetter(Method method) {
    if (!method.getName().startsWith("set"))
        return false;
    if (method.getParameterTypes().length != 1)
        return false;
    return true;
}
基本上,我在这里所做的工作如下:

一,。将newCompany中getter的所有结果放入名为hm的HashMap中

二,。浏览公司的Getter结果。如果hm不包含公司中getters的任何一个结果,那么这两家公司被认为是不同的

三,。如果两家公司不同,请将公司中的值设置为新公司中的值

public static void compareAndApplyDifferences(Object o1, Object o2) {
    if(!o1.getClass().equals(o2.getClass())) {
        return;
    }
    // check if the result of getters in o1 and o2 are different
    boolean isDiff = false;
    Class<? extends Object> c1 = o1.getClass();
    Class<? extends Object> c2 = o2.getClass();
    Method[] methods1 = c1.getMethods();
    Method[] methods2 = c2.getMethods();
    Map<String, Object> hm = new HashMap<String, Object>();
    for (Method method2 : methods2) {
        if (isGetter(method2)) {
            try {
                Object getterResult = method2.invoke(o2);
                hm.put(method2.getName().substring(3), getterResult);
            } catch (IllegalAccessException e) {
            } catch (IllegalArgumentException e) {
            } catch (InvocationTargetException e) {
            }
        }
    }
    for (Method method1 : methods1) {
        if (isGetter(method1)) {
            try {
                String getterResult = (String) method1.invoke(o1);
                if (!hm.containsValue(getterResult)) {
                    isDiff = true;
                    break;
                }
            } catch (IllegalAccessException e) {
            } catch (IllegalArgumentException e) {
            } catch (InvocationTargetException e) {
            }
        }
    }

    if (isDiff) {
        // set the values in o1 as the values in o2
        for (Method method1 : methods1) {
            if (isSetter(method1)) {
                try {
                    method1.invoke(o1, hm.get(method1.getName().substring(3)));
                } catch (IllegalAccessException e) {
                } catch (IllegalArgumentException e) {
                } catch (InvocationTargetException e) {
                }
            }
        }
    } else {
        return;
    }
}

private static boolean isGetter(Method method) {
    if (!method.getName().startsWith("get"))
        return false;
    if (method.getParameterTypes().length != 0)
        return false;
    if (void.class.equals(method.getReturnType()))
        return false;
    return true;
}

private static boolean isSetter(Method method) {
    if (!method.getName().startsWith("set"))
        return false;
    if (method.getParameterTypes().length != 1)
        return false;
    return true;
}

没有真正的实用程序可以“发现并应用”差异(据我所知),但是,有反射(如其他人所说),比如apachecomparator(这是一个强大的类)

至于“应用差异”,Apache中还有一个工具(这次是BeanUtils):它是“
copyProperties(objectO1,objectO2)
”,wihchi会将所有属性(字段)从一个对象复制到另一个对象

因此,您只需比较对象,如果它们存在差异,请将一个复制到另一个


除了性能问题,我不明白为什么只复制不同的字段(因为如果复制相同的字段,那么就不会有任何差异)。如果你必须只复制不同的字段,我想你必须自己制作工具。

不知道,但看看这是否符合你的要求,我就把它留在这里:。谢谢virendrao,我对此进行了研究。请阅读我的问题:是否有任何实用工具/库可以简单地找到这两个对象之间的所有差异,并将更改应用于公司实例?谢谢您的回答。基本上,我可以通过使用ApacheCommons中的两个UTIL来实现这一点。谢谢你的回答。有这个工具很好,我会深入研究。为了与第三方的现有库实现“快速双赢”,我选择了另一个作为答案。很抱歉:-)