2011-02-15 30 views
8

Dadas dos listas, cada lista con el mismo tipo de objeto, me gustaría encontrar objetos entre las dos listas que coinciden, en función de algunos valores de propiedad.java - ¿Cómo encontrar objetos coincidentes entre dos listas?

p. Ej. un objeto de Lista1, L1Obj, coincide con un objeto de Lista2, L2Obj, si L1Obj.a == L2Obj.a Y L1Obj.b == L2Obj.c Y L1Obj.c == L2Obj.c

Estas propiedades no son las únicas propiedades de la clase, pero son todo lo que se necesita para identificar de manera única un objeto dentro de una lista.

Mi pregunta es: ¿cuál es la mejor manera de lograr esto?

Una forma sería construir HashMaps basándose en las listas, con el valor de Cadena concatenado de a + b + c utilizado como la clave para indexar un objeto. De esa forma podría recorrer la primera lista e intentar buscar un objeto en la segunda lista con la misma clave.

¿Cómo te suena? ¿Hay una mejor manera de lograr esto?

¡Toda ayuda es muy apreciada!


ACTUALIZACIÓN:

bien, lo que en realidad necesitan un poco más. Al encontrar una coincidencia, quiero sobrescribir las propiedades L1Obj.x, L1Obj.y, L1Obj.z con las de L2Obj. HashSet suena genial para encontrar coincidencias, pero si estoy en lo cierto, en realidad no me permite acceder a estas coincidencias.

¿Qué puedo hacer al respecto?

+0

¿Puedes editar el código de las clases almacenadas en las listas? – Alb

+0

@Alb sí Puedo editar el código – QuakerOat

Respuesta

8

¿Los objetos que desea observar implementan equals(Object) y hashCode() que solo tienen en cuenta los campos que le interesan? Si es así, puede crear un nuevo HashSet de la primera lista, y luego llamar al retainAll() pasando en la segunda lista.

Si no se implementan equals(Object) y hashCode() con respecto a las propiedades que le interesan, puede crear un TreeSet y pasar en un Comparator que se ve en las propiedades que le interesan.

+0

Uso agradable y apropiado de 'retainAll' –

0

No sé si pensar que es fácil, pero me gustaría tratar de esa manera:

Sustituir el método equals del objeto para implementar su comparación para comprobar si se trata del mismo objeto

Entonces Yo iteraría sobre la primera lista y verificaría con el método contains si el objeto también está contenido en la segunda lista.

Luego, repetiría la segunda lista y verificaría si el objeto también está en la primera lista y no está en la lista de resultados.

3

En lugar de utilizar el repesntation String, utilizar el método equals() un HashSet como tan:

class MyObj { 

    Property a; 
    Property b; 
    Property c; 

    public boolean equals(Object o) { 
     // use == if Property is primitive, like int or something 
     return o instanceof MyObj && a.equals(o.a) && b.equals(o.b) && c.equals(o.c); 
    } 

    // edit - when you override equals, also override hashcode 
    public int hashCode() { 
     return a.hashCode()^b.hashCode()^c.hashCode(); 
    } 

    public String toString() { 
     return a.toString() + " " + b.toString() + " " + c.toString(); 
    } 

} 

// later in your main method 
Set<MyObj> objSet = new HashSet<MyObj>(); 
for(MyObj o : list1) objSet.add(o); 
for(MyObj o : list2) if(objSet.contains(o)) System.out.println(o + " is a match!"); 
+0

Debe cambiar 'igual (MyObj o)' a 'igual (Objeto o)'. No anula iguales según lo escrito. – ILMTitan

+0

@Titan - Me di cuenta de que hashCode faltaba antes de tu comentario :). Pensé que podrías dejarlo como MyObj, pero lo limpiaré para que coincida con los estándares. – corsiKa

0

El objeto en cuestión debe implementar el método boolean equals(Object). Por ejemplo:

L1Obj.equals(L2Obj); 

Puede sobrecargar ese método para que pueda implementar las operaciones de igualdad que desee.

1

Puede hacer una cosa. Tenga dos listas con estos objetos y anule el método equals de la clase a la que pertenecen estos objetos. Su método equals debe ser similar

@Override 
public boolean equals(Object obj) 
{ 
    return (this.a == obj.a && this.b == obj.b && this.c == obj.c) 

} 

Asimismo, recuerda, una vez que se reemplaza es igual método, es necesario reemplazar el método int hashCode() también.

Una cosa a tener en cuenta es que al implementar hashCode() es que 2 objetos iguales tendrán el mismo hashCode, mientras que el inverso no es verdadero.

Cuestiones relacionadas