Gleichheit von Objekten wird bekanntlich mittels „equals“ Methode implementiert in der fachliche Informationen heran gezogen werden um zu prüfen ob es sich bei zwei Objektinstanzen um ein und dasselbe fachliche Objekt handelt. Es mag aber nun Situationen geben in denen uns das nicht reicht. Denken wir an einen JUnit-Test oder ein Migrationsprogramm wo möglicherweise weitreichendere Prüfungen auf Gleichheit durchgeführt werden sollen. Die Apache Commons Lang Bibliothek hat da was in petto : der CompareToBuilder
Ich bin du?
Die einfachste Variante den CompareBuilder zu verwenden ist es über die Fluent-API alle Vergleichswerte über die „append“ Methode ein zu binden und am Ende mittels „toComparison“ Methode das entsprechende Ergebnis an zu fordern. Der CompareToBuilder führt dann null-Prüfungen durch und ruft für jedes übergeben Objekt die „equals“ Methode auf und liefert am Ende einen int-Wert zurück der die Gleichheit der beiden Objekte ausweist.
int cResultFirma = new CompareToBuilder() .append(firma1.getFax(), firma2.getFax()) .append(firma1.getInternet(), firma2.getInternet()) .append(firma1.getMail(), firma2.getMail()) .append(firma1.getTelefon(), firma2.getTelefon()) .toComparison();
Weniger schreiben, mehr Reflection
Das gezeigte Beispiel ist für komplexe Objekte natürlich ein aufwendiges Unterfangen. Der CompareToBuilder bietet darüber hinaus aber noch eine statische Methode die es erlaubt solche Prüfungen per Reflection durchführen zu lassen. Dabei bietet die Methode auch die Möglichkeit bestimmte Felder nicht aus zu werten, transiente Felder zu ignorieren oder die Prüfung nicht auf alle Felder der Superklassen an zu wenden.
int cResultFirma = CompareToBuilder.reflectionCompare( firma1, firma2, // zu vergleichende Objekte "id", "createTimestamp" // Felder die nicht geprüft werden sollen );
Was auf den ersten Blick sehr einfach in der Verwendung aussieht ist allerdings leider auch in seiner Funktionalität sehr eingeschränkt. So stößt dieser Mechanismus schon auf Probleme wenn es sich bei den zu prüfenden Feldern um eine Collection von Objekten handelt. Auch ist es leider nicht möglich auf bestimmte Attribute mit einer separaten Prüfungen zu reagieren. So wäre es z.B. wünschenswert beim Vergleich unserer Firma mittels Reflection eine referenzierte Instanz „Adresse“ nicht mittels „equals“ prüfen zu lassen sondern auch hier per Reflection zu prüfen oder individuell zu prüfen. Das lässt sich somit leider nur über den Umweg realisieren solche Referenzen beim „reflectionCompare“ in die Ignore-Liste mit auf zu nehmen und diese separat zu prüfen.
Der CompareToBuilder aus der Bibliothek Apache Commons Lang ist ein sehr rudimentäres Hilfsmittel das uns hilft Vergleiche von Objekten an zu stellen. Wenn diese allerdings sehr komplexe Strukturen aufweisen, die vollständig geprüft werden sollen, stößt der CompareToBuilder sehr schnell an seine Grenzen