21

我一直在尝试探索 org.apache.commons.beanutils 库的方法/习语来评估2 个实例之间的所有属性是否相等,即 bean 的通用 equals() 方法。
有没有一种简单的方法来做这个usnig这个库?还是我以错误的方式解决这个问题?谢谢。

4

4 回答 4

23

试试commons-langEqualsBuilder.reflectionEquals()。EqualsBuilder 有一组方法来包含所有字段、所有非瞬态字段以及除某些字段之外的所有字段。

如果一切都失败了,代码可以作为一个很好的例子来实现它。

于 2009-01-23T12:26:36.910 回答
8

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

关于 equals() 和 hashcode() 的行为有一些规则。这些规则讨论了对称性、一致性和自反性,当您的 equals 方法根据您传入的其他对象动态运行时,这可能很难做到。

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

一般来说,我认为你最好创建自己的 hashcode 和 equals 方法。有一些很好的插件可以根据类属性自动为您生成该代码。

说了这么多,下面是一些我很久以前写的获取 getter、setter 和属性的(旧式)方法:

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;
}

吸气剂:

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;
}

也许你可以用它来滚动你自己的。

编辑:当然,Aaron Digulla 的回答中的反射生成器比我的手艺要好得多。

于 2009-01-23T11:50:18.200 回答
2

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

于 2009-01-23T13:22:07.283 回答
0

或者,虽然不是您问题的直接答案,但它可能是您问题的答案(即在超快的同时消除做样板代码的工作)

如果您使用 Eclipse,以下步骤将自动为您生成 hashCode 和 equals:

来源 > 生成 hashCode 和 equals...

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

干杯,我希望它可以帮助任何来到这里的人,目的是减少一些时间编写样板。

PS:我相信其他流行的 IDE 肯定也有类似的功能。

于 2016-01-30T16:45:10.803 回答