如何一般比较整个java bean?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/472626/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:04:25  来源:igfitidea点击:

how to generically compare entire java beans?

javajavabeans

提问by ysouter

I've been trying to grok the org.apache.commons.beanutils library for a method/idiom to evaluate for equality allproperties between 2 instances i.e. a generic equals() method for beans.
Is there a simple way to do this usnig this library? Or am I going about this the wrong way? Thanks.

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

采纳答案by Aaron Digulla

Try EqualsBuilder.reflectionEquals()of commons-lang. EqualsBuilder has a set of methods to include all fields, all non-transient fields and all but certain fields.

尝试EqualsBuilder.reflectionEquals()公共浪。EqualsBuilder 有一组方法来包括所有字段、所有非瞬态字段和除某些字段之外的所有字段。

If all else fails, the code could serve as a good example how to implement this.

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

回答by Rolf

To answer your question directly, you could use reflection to do equality checking of beans. There are a few snags you need to be aware of.

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

There are rules regarding the behaviour of equals() and hashcode(). These rules talk about symmetry, consitency and reflexiveness which may be hard to do when your equals method behaves dynamically based on the other object you're passing in.

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

Interesting read: http://www.geocities.com/technofundo/tech/java/equalhash.html

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

Generally speaking, I think you are better off creating your own hashcode and equals methods. There are a fwe good plugins which can automatically generate that code for you based on the class properties.

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

Having said all this, here are some (old style) methods for getting getters, setters and properties I wrote a long time ago:

说了这么多,这里有一些(旧式)方法来获取我很久以前写的 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;
}

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

And the Setters:

和二传手:

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

Maybe you can use this to roll your own.

也许你可以用它来推出你自己的。

Edit:Ofcourse the reflectionbuilderin Aaron Digulla's answeris much better than my handywork.

编辑:当然,Aaron Digulla 的回答中反射构建器比我的手工好得多。

回答by Rahel Lüthy

As mentioned above, a reflection-based implementation will do what you want. I just wanted to warn you, that reflection is quite costly and such an implementation could be comparably slow. If you just need to do occasional comparisons, you will be fine. However, if you have huge datasets and frequent equality checks (e.g. filtering of big tables) you might get into trouble.

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

回答by Jo?o Antunes

Or, although not a direct answer to your question, but it might be an answer to your problem (i.e. remove the effort of doing boilerplate code whilebeing super fast)

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

if you use Eclipse, the following steps will auto generate the hashCode and equals for you:

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

Source > Generate hashCode and equals...

源 > 生成 hashCode 并等于...

and then select the fields, it's super effective! :D

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

Cheers and I hope it helps whoever comes here with the purpose of cutting some time writing boilerplate.

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

PS: I'm sure other popular IDEs must have similar features.

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