深度递归对象比较(再次)

时间:2015-04-03 09:37:58

标签: java reflection compare

SO上有两个类似的问题:

Is there a Java reflection utility to do a deep comparison of two objects?

Deep reflective compare equals

但是,很有趣,他们都没有给出完全正确的答案。

我和其他问题的作者真正想要的是,某些库中的一些方法只会告诉两个对象是否相等:

boolean deepEquals(Object obj1, Object obj2)

即。没有抛出任何例外,等等。

apache的{​​{1}}不是这样,因为它没有深入比较。

EqualsBuilder似乎也是错误的决定,因为它的方法不会返回Unitilstrue;如果比较失败,它只会引发异常。当然,它可以像这样使用:

false

但它似乎非常难看,Difference difference = ReflectionComparatorFactory.createRefectionComparator(new ReflectionComparatorMode[]{ReflectionComparatorMode.LENIENT_ORDER, ReflectionComparatorMode.IGNORE_DEFAULTS}).getDifference(oldObject, newObject);库似乎对于所需的比较目的而言似乎太难了。

此外,很清楚如何通过self创建这样的unitils,但是不太可能没有包含已经实现的方法的常用库。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

Java 1.7有Objects.deepEquals(Object a, Object b)

不幸的是,Unitils的{​​{1}}类没有附带方法返回ReflectionAsserttrue。你可以尝试:

https://github.com/jdereg/java-util

false班级有DeepEqualsDeepEquals.deepEquals(Object a, Object b)个方法,您可以使用这些方法覆盖班级的DeepEquals.deepHashCode(Object o)equals方法,或在外部使用hashCode 1}}或Comparator

注意:此DeepEquals实现有一个限制。如果类具有用户定义的重写等于方法,那将优先。

答案 1 :(得分:2)

我不认为Apache EqualsBuilder是一个可怕的答案,但是对于一个能够做你想要的简单界面,你需要稍微包装一下。这是一个例子。

public static <T> boolean matches(T actual, T expected, String... excludedFields) {
    assert actual != null;
    assert expected != null;
    boolean matches = EqualsBuilder.reflectionEquals(actual, expected,
            false /* testTransients */,
            null /* reflectUpToClass */,
            true /* testRecursive */,
            excludedFields);
    if (!matches) {
        log.warn("Actual result doesn't match.");
        logComparison(actual, expected);
    }
    return matches;
}

public static <T>  void logComparison(T actual, T expected) {
    //Making sure hashcodes don't thrown an exception
    assert actual.hashCode() > Integer.MIN_VALUE;
    assert expected.hashCode() > Integer.MIN_VALUE;
    log.warn("Expected: \n" + reflectionToString(expected));
    log.warn("Actual: \n" + reflectionToString(actual));
}