2011-09-07 23 views
6

Quiero comparar dos objetos Java sin reemplazar es igual al método. Como necesito anular el método de igualdad en n cantidad de clases que tengo, necesito un método de utilidad común donde podamos comparar dos objetos de Java.Método común para comparar dos objetos Java

Algo como:

A a1,a2; 
B b1,b2; 
C c1,c2; 
----- 
----- 
boolean isEqual1 = new ObjectComparator().isEquals(a1 , a2); 
boolean isEqual2 = new ObjectComparator().isEquals(b1 , b2); 
boolean isEqual3 = new ObjectComparator().isEquals(c1 , c2); 

por favor me ayude a escribir una utilidad común para comparar cualquier objetos Java

Esperanza utilizando Field clase y getClass método que puede lograrlo. Por favor guíame.

+0

http://www.unitils.org/apidocs/org/unitils/reflectionassert/ReflectionComparator.html mira esto. – amod

Respuesta

9

Eche un vistazo a EqualsBuilder.reflectionEquals en la biblioteca de Apache Commons.

Desde el documentation:

Este método utiliza la reflexión para determinar si los dos objetos son iguales.

Utiliza AccessibleObject.setAccessible para obtener acceso a campos privados. Esto significa que emitirá una excepción de seguridad si se ejecuta bajo un administrador de seguridad, si los permisos no están configurados correctamente. Tampoco es tan eficiente como las pruebas explícitamente.


Así, en su ejemplo se vería así:

A a1,a2; 
B b1,b2; 
C c1,c2; 
----- 
----- 
boolean isEqual1 = EqualsBuilder.reflectionEquals(a1 , a2); 
boolean isEqual2 = EqualsBuilder.reflectionEquals(b1 , b2); 
boolean isEqual3 = EqualsBuilder.reflectionEquals(c1 , c2); 
+0

Muchas gracias. Eso me dio un comienzo. Necesito personalizar esa clase para agregar ciertas características como, agregar una exunción a un campo desde la comparación, etc. ¿La clase EqualsBuilder me ayudará a lograr esas características extendiendo esa clase? –

+0

ADVERTENCIA: de acuerdo con EqualsBuilder.reflectionEquals (Object lhs, Object rhs) Javadoc "Los miembros transitorios no se probarán". Entonces, EqualsBuilder.reflectionEquals (new Date (2), new Date (3)) devolverá verdadero. Mejor uso reflectionEquals (Object lhs, Object rhs, boolean testTransients). – machinery

2

Trate Apache Commons EqualsBuilder#reflectionEquals método y comprobar si cumple con sus necesidades.

+1

ADVERTENCIA: según EqualsBuilder.reflectionEquals (Object lhs, Object rhs) Javadoc "Los miembros transitorios no se probarán". Entonces, EqualsBuilder.reflectionEquals (new Date (2), new Date (3)) devolverá verdadero. Mejor uso reflectionEquals (Object lhs, Object rhs, boolean testTransients). – machinery

3

Esto puede ser lo que buscas EqualsBuilder.reflectionEquals

public boolean equals(Object obj) { 
    return EqualsBuilder.reflectionEquals(this, obj); 
} 
+0

* [...] sin anular el método equals [...] * (+1 para todos modos ;-) – aioobe

+0

Es un ejemplo del documento al que puede llamar sin anularlo. ;) –

+1

ADVERTENCIA: de acuerdo con EqualsBuilder.reflectionEquals (Object lhs, Object rhs) Javadoc "Los miembros transitorios no se probarán". Entonces, EqualsBuilder.reflectionEquals (new Date (2), new Date (3)) devolverá verdadero. Mejor uso reflectionEquals (Object lhs, Object rhs, boolean testTransients). – machinery

1

En primer lugar, ¿existe una razón de peso por la que no desea utilizar el método es igual? El método equals es usado internamente por las clases de colección y tal que deberá obedecer el contrato igual.

Si hay una, entonces sí, puede hacer una comparación de campo por campo usando la reflexión. Obtenga el list of fields de la clase y para cada campo check the value. También deberá asegurarse de que ambos sean instancia de la misma clase por adelantado.

+1

La razón de peso es que mi clase puede crecer con más campos. todas y cada una de las veces también necesito actualizar el método igual. –

0

¿Quieres Objects.equals(a,b) disponibles en Java 1.7, en el paquete java.util

Si está utilizando una versión anterior a Java 1.7, puede utilizar una de las bibliotecas que otras personas han sugerido, en particular el proyecto Apache Commons .

+3

Quiere decir aquí Objects.deepEquals (a, b). Objects.equals (a, b) solo usa las implementaciones predeterminadas equals() de los objetos, pero puede manejar valores nulos. – Asturio

0

Es posible que desee considerar el uso de Shazamcrest.

Desde su página de GitHub:

Tener un grano Person con la siguiente estructura:

Person person 
    |-- String name 
    |-- String surname 
    |-- Address address 
     |-- String streetName 
     |-- int streetNumber 
     |-- String postcode 

para comparar dos Person frijoles con Shazamcrest escribiríamos:

assertThat(actualPerson, sameBeanAs(expectedPerson)); 
0

Prueba esto. Esto funciona a la perfección pero necesita más espacio en montón si los objetos que compara son enormes. org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals (obj1, obj2)

http://www.unitils.org/

Usted puede obtener el tarro desde abajo.

<!-- https://mvnrepository.com/artifact/org.unitils/unitils --> 
     <dependency> 
      <groupId>org.unitils</groupId> 
      <artifactId>unitils</artifactId> 
      <version>2.2</version> 
     </dependency>