Comparison of deep recursive objects (again)

There are two similar questions on SO:

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

Deep reflective comparison equals

but, it’s funny, not one of them gives a completely correct answer to the question.

What I and other authors really like is some kind of method in some library that just says that two objects are equal or not:

boolean deepEquals(Object obj1, Object obj2)

i.e. without any exceptions etc.

apache EqualsBuilder is wrong because it is not much compared.

Unitils also a bad solution because its method does not return true or false ; it just throws an exception if the comparison was unsuccessful. Of course, it could be used as follows:

Difference difference = ReflectionComparatorFactory.createRefectionComparator(new ReflectionComparatorMode[]{ReflectionComparatorMode.LENIENT_ORDER, ReflectionComparatorMode.IGNORE_DEFAULTS}).getDifference(oldObject, newObject);

but it seems very ugly, and the Unitils library completely seems too complex for the required comparison purposes.

In addition, it is completely clear how to create such deepEquals for yourself, but it is unlikely that there are no common libraries used that contain an already implemented method like this. Any ideas?

+7
java reflection compare
source share
2 answers

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

Unfortunately, the Unitils ReflectionAssert class Unitils not have an accompanying method that returns true or false . You can try:

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

whose DeepEquals class has the DeepEquals.deepEquals(Object a, Object b) and DeepEquals.deepHashCode(Object o) methods, which you can use to override the methods of the equals and hashCode class or use them in an external Comparator or Equivalence .

Note. This implementation of DeepEquals has a limitation. If the class has user-defined overridden peer methods, this will take precedence.

+1
source share

I don't think Apache EqualsBuilder is a terrible answer, but for a simple interface that does what you want, you need to transfer the call a bit. Here is an example.

 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)); } 
0
source share

All Articles