2010-08-11 24 views
6

Tengo dos instancias de la misma clase. Necesito encontrar propiedades que sean diferentes entre ellas (básicamente, el valor de la propiedad, por ejemplo, FirstName podría ser diferente en ambas). Los campos son primitivos, complejos y también colecciones.Diferencia entre dos instancias de la misma clase

Básicamente, necesito encontrar diferencias entre dos instancias y si los campos son diferentes en ambas instancias, copiaré el valor del campo desde la primera instancia a una tercera instancia (objeto diff).

Creo que puedo usar la reflexión, pero las clases son muy complejas y pueden llegar a ser propensas a errores.

+1

Hm ... no hay dos beans de Java iguales ... http://www.coffeeobsessed.net/wp-content/uploads/2010/02/kawa-java-beans.jpg –

Respuesta

1

escribir un método como

public YourClass diff(YourClass other) { 
    // diff code here 
} 

o

public static YourClass diff(YourClass first, YourClass second) { 
    // diff code here 
} 

y envolver algunas pruebas de unidad en torno a las implementaciones.

reflexión puede parecer más complicado, pero tiene las siguientes ventajas:

1) Puede ser genérico y se puede hacer el mismo trabajo código con cualquier clase
2) No tendrá que ser cambiado si la clase evoluciona

Si desea ir con la reflexión, puede utilizar Class.getDeclaredFields() (google para "java class api 6") para obtener todos los campos de la clase, y luego puede utilizar la API de campo para obtener la valores para un objeto. Si quieres ser realmente elegante, tienes un String [] "diffIgnoredFields" estático e incluye los nombres de campo que deseas ignorar en el diff.

+1

-1. Esta respuesta no proporciona ningún detalle de implementación para la parte que es realmente desafiante. –

+0

@mike, ¿qué tal ahora? – hvgotcodes

+0

@hvgotcoes, sí. Deshice mi voto negativo. El "código Diff aquí" no fue una muy buena respuesta a una pregunta sobre cómo escribir el código diff. –

2

No hay otra manera que utilizar la reflexión si desea hacerlo de forma genérica. Si sus campos tienen getters, entonces podría seguir comparándolo con el método equals. Entonces ya conoce los campos en tiempo de compilación.

+2

Este es un problema difícil. Dado que los objetos son realmente punteros disfrazados, uno debe ser capaz de distinguir entre x.a y x.b apuntando al mismo objeto, y x.a y x.b apuntando a dos objetos diferentes, que son iguales entre sí. Por cierto, todos los miembros y miembros de los miembros deben implementar 'IComparable' correctamente, o algo así. Además, la calculadora diff tendrá dificultades para comparar diccionarios, creo. ¿Qué hace que dos diccionarios o conjuntos sean iguales? ¿Tienen que ser lo mismo bajo el capó? –

4

Su pregunta no está nada clara. Primero dijiste "dos instancias de la misma clase", luego dijiste "las clases son muy complejas". ¿Es esta una solución genérica para encontrar diferencias entre instancias para cualquier clase, o es solo un caso específico? La otra ambigüedad es lo que quiere decir con "copiar las diferencias". Por ejemplo, si es una Cadena, ¿cuál es la diferencia entre las dos cadenas que se copiarían en la nueva instancia? Si es una colección, ¿cuál es la diferencia entre las colecciones? ¿Qué pasa si tiene dos ArrayLists que tienen las mismas cosas en diferentes órdenes?

Si es un caso específico, entonces puede simplemente crear un método en la clase donde pasa en una instancia de la misma clase. Luego puedes iterar sobre cada campo y comparar las diferencias.

public TheClass difference(TheClass that) { 
    TheClass newClass = new TheClas() 
    if (this.getName().equals(that.getName()) == false) { 
    newClass.setName(that.getName()); 
    } 
    ... 
} 

Pero esto puede salirse de control dependiendo de qué tan profundo sea el gráfico de objetos.

Quizás el patrón de generador podría ser útil aquí si está intentando construir una solución genérica/reutilizable. Puede consultar la base de código de Apache Commons y ver cómo implementan HashCodeBuilder y ToStringBuilder. Incluso tienen una versión de reflexión de las utilidades. Vea cómo manejan iguales profundos y poco profundos.

+1

* "Pero esto puede salirse de control dependiendo de qué tan profundo sea el gráfico de objetos" * ... y se vuelve aún más complejo si el gráfico no está estructurado en árbol. –

Cuestiones relacionadas