如何一般地比较整个java bean?

时间:2009-01-23 11:41:09

标签: java javabeans

我一直在尝试使用org.apache.commons.beanutils库来获取方法/习惯用法来评估两个实例之间的相等所有属性,即bean的通用equals()方法。
有没有一种简单的方法可以使用这个库?或者我是以错误的方式来做这件事的? 感谢。

4 个答案:

答案 0 :(得分:18)

尝试EqualsBuilder.reflectionEquals()commons-lang。 EqualsBuilder有一组方法可以包含所有字段,所有非瞬态字段以及除特定字段外的所有字段。

如果所有其他方法都失败了,那么代码可以作为一个很好的例子来实现它。

答案 1 :(得分:7)

要直接回答您的问题,您可以使用反射来对bean进行相等性检查。你需要注意一些障碍。

有关于equals()和hashcode()行为的规则。这些规则讨论了对称性,顺从性和反身性,当你的equals方法基于你传入的另一个对象动态行为时,这可能很难做到。

有趣的阅读: http://www.geocities.com/technofundo/tech/java/equalhash.html

一般来说,我认为你最好创建自己的哈希码并等于方法。有一个很好的插件可以根据类属性为你自动生成代码。

说完这一切之后,这里有一些(旧式)方法来获取我很久以前写过的getter,setter和properties:

private Map getPrivateFields(Class clazz, Map getters, Map setters) {
    Field[] fields = clazz.getDeclaredFields();
    Map m = new HashMap();
    for (int i = 0; i < fields.length; i++) {
        int modifiers = fields[i].getModifiers();
        if (Modifier.isPrivate(modifiers) && !Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) {
            String propName = fields[i].getName();
            if (getters.get(propName) != null && setters.get(propName) != null) {
                m.put(fields[i].getName(), fields[i]);
            }
        }
    }
    return m;
}

The Getters:

private Map getGetters(Class clazz) {
    Method[] methods = clazz.getMethods();
    Map m = new HashMap();
    for (int i = 0; i < methods.length; i++) {
        if (methods[i].getName().startsWith("get")) {
            int modifiers = methods[i].getModifiers();
            if (validAccessMethod(modifiers)) {
                m.put(getPropertyName(methods[i].getName()), methods[i]);
            }
        }
    }
    return m;
}

塞特犬:

private Map getSetters(Class clazz, Map getters) {
    Method[] methods = clazz.getMethods();
    Map m = new HashMap();
    for (int i = 0; i < methods.length; i++) {
        if (methods[i].getName().startsWith("set")) {
            int modifiers = methods[i].getModifiers();
            String propName = getPropertyName(methods[i].getName());
            Method getter = (Method) getters.get(propName);

            if (validAccessMethod(modifiers) && getter != null) {
                Class returnType = getter.getReturnType();
                Class setType = methods[i].getParameterTypes()[0];
                int numTypes = methods[i].getParameterTypes().length;

                if (returnType.equals(setType) && numTypes == 1) {
                    m.put(propName, methods[i]);
                }
            }
        }
    }
    return m;
}

也许你可以用它自己动手。

编辑:当然,reflectionbuilder中的Aaron Digulla's answer比我的工作要好得多。

答案 2 :(得分:2)

如上所述,基于反射的实现可以满足您的需求。我只是想警告你,这种反思是相当昂贵的,而且这样的实现可能会相对缓慢。如果你只需要偶尔进行比较,你会没事的。但是,如果您有大量数据集和频繁的相等性检查(例如过滤大表),您可能会遇到麻烦。

答案 3 :(得分:-1)

或者,虽然不能直接回答你的问题,但它可能是你问题的答案(即在超快的时候删除了做样板代码的努力)

如果您使用Eclipse,以下步骤将自动为您生成hashCode并等于:

来源&gt;生成hashCode并等于...

然后选择字段,它超级有效! :d

干杯,我希望无论是谁来到这里都是为了减少编写样板的时间。

PS:我确信其他流行的IDE必须具有类似的功能。