2009-01-23 9 views
15

He intentado asimilar la biblioteca org.apache.commons.beanutils para un método/modismo para evaluar la igualdad todas las propiedades entre 2 instancias, es decir, un método genérico equals() para beans.
¿Hay una manera simple de hacer esto usando esta biblioteca? ¿O estoy yendo sobre esto de la manera incorrecta? Gracias.cómo comparar genéricamente granos enteros de Java?

+0

La [biblioteca de xtendbeans] (http://stackoverflow.com/a/39222891/421602) podría ser de interés en este contexto; ver [el ejemplo completo en esta otra pregunta SO] (http://stackoverflow.com/a/39222891/421602). – vorburger

Respuesta

16

Probar EqualsBuilder.reflectionEquals() de commons-lang. EqualsBuilder tiene un conjunto de métodos para incluir todos los campos, todos los campos no transitorios y todos los campos excepto ciertos.

Si todo lo demás falla, el código podría servir como un buen ejemplo de cómo implementar esto.

+3

Tenga en cuenta que esto no es recursivo, por lo que si ha anidado beans (es decir, una propiedad de un bean es otro bean), necesidad de implementar iguales a sí mismos. 'reflectionEquals' solo llama a' igual' en cada propiedad, no se refleja en la clase más. – artbristol

+1

@artbristol: +1 pero tenga cuidado será recursivo igual: Usted puede quedar atrapado fácilmente en un bucle cuando los frijoles forman ciclos. –

7

Para responder a su pregunta directamente, puede usar el reflejo para hacer una comprobación de igualdad de los beans. Hay algunos inconvenientes que debes tener en cuenta.

Existen reglas sobre el comportamiento de equals() y hashcode(). Estas reglas hablan de simetría, consitency y reflexividad que puede ser difícil de hacer cuando su método equals se comporta de forma dinámica en el otro objeto que está pasando en

lectura interesante:. http://www.geocities.com/technofundo/tech/java/equalhash.html

En términos generales, creo es mejor que crees tu propio código hash e iguales métodos. Hay muchos complementos buenos que pueden generar automáticamente ese código en función de las propiedades de la clase.

Una vez dicho todo esto, aquí hay algunos (estilo antiguo) métodos para obtener getters, organismos y las propiedades que escribí hace mucho tiempo:

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

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

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

Tal vez pueda usar esto para hacer su propio.

Editar: Por supuesto la reflectionbuilder en Aaron Digulla's answer es mucho mejor que mi handywork.

+0

getters booleanos se llaman isFoo(), por lo que el código necesitaría una pequeña mejora en getGetters() –

2

Como se mencionó anteriormente, una implementación basada en la reflexión hará lo que usted desee. Solo quería advertirles que esa reflexión es bastante costosa y que una implementación de este tipo podría ser comparativamente lenta. Si solo necesitas hacer comparaciones ocasionales, estarás bien. Sin embargo, si tiene grandes conjuntos de datos y frecuentes controles de igualdad (por ejemplo, filtrado de tablas grandes), puede tener problemas.

+0

Buen punto de hecho. jguru tiene una buena comparación en línea: http://www.jguru.com/faq/view.jsp?EID=246569 – Rolf

0

O, aunque no es una respuesta directa a su pregunta, pero podría ser una respuesta a su problema (es decir, eliminar el esfuerzo de hacer código repetitivo mientras ser súper rápido)

si utiliza Eclipse, la siguientes pasos de auto generar el código hash y es igual para usted:

Fuente> generar código hash y es igual a ...

y luego seleccionar los campos, es super eficaz!: D

Saludos y espero que ayude a cualquiera que venga aquí con el propósito de cortar algo de tiempo escribiendo un texto repetitivo.

PD: estoy seguro de que otros IDEs populares deben tener características similares.

Cuestiones relacionadas