2012-01-17 53 views
7

Tengo dos clases de Pojo con campos diferentes con ID único.intersección de dos listas de objetos diferentes en java

Quiero realizar la intersección de dos List<A> y List<B>.

¿Cuál es la mejor manera de hacerlo? Una es que simplemente puedo iterar dos veces pero luego la complejidad es demasiado alta n2.

¿Hay alguna forma mejor de hacerlo? ¿Puedo hacerlo con Comparator?

Class A { 
Id, Name ,DOB} 

Class B{ 
id, aid ,location } 

que tienen lista de A, B y Lista de

ahora quieren obtener la lista de A con B ubicación en

+0

posible duplicado de [¿Hay una manera de calcular la intersección de dos conjuntos?] (Http: // stackoverflow .com/questions/8882097/is-there-a-way-to-calculate-the-intersection-of-two-sets) – Bohemian

+0

¿Están ordenadas sus listas (en id/id)? –

+1

@Bohemian, 'Set' y' List' no son lo mismo. – Paul

Respuesta

3

Apache Commons Collections tiene un método para hacer esto: CollectionUtils.intersection. No usa genéricos, sin embargo.

Se da también una cuestión de forma: List intersection in java

+0

Es importante tener en cuenta que CollectionUtils.intersection no garantiza el orden de los elementos en el resultado (su tipo de devolución es una Colección). Como estás tratando con Listas, ten esto en cuenta. – NBJack

+0

Si el orden es importante, debes probar ListUtils.intersection. – NBJack

2

Se puede poner elementos de List<B> en un HashMap<Integer,B>, con el id siendo la clave.

Hecho esto, puede iterar sobre los elementos de List<A> y buscar rápidamente los elementos correspondientes B usando el mapa hash. Eso proporcionará la estructura que necesita ("lista de A con ubicación en B").

+0

-1 Tienes que estar bromeando.* Realmente * solución de mierda, pero si debe hacerlo así, use un 'Set', no un' Map' (de todos modos solo está usando el conjunto de claves del mapa, ¿le parece familiar ... keySET? ... * * SET **?) Geez ... – Bohemian

+1

@Bohemian: Es evidente que tienes una solución diferente en mente. ¿Por qué no continúas y lo publicas como respuesta? – NPE

+1

Desafío justo: he publicado una solución. Era el final de un largo día, perdón por el 'tude'. Podría haberlo dicho mejor. Sin embargo, sigue siendo cierto que un 'Mapa' es la herramienta incorrecta – Bohemian

2
  1. Ordene la lista en orden ascendente de Id.

  2. de inicio con la Lista A, y encontrar índice correspondiente en la lista B de Recuerde que el índice actual de la lista B. decir (endB)

  3. de inicio con el siguiente índice de la Lista A, y comparar en la Lista B a partir de (indB + 1)

  4. repita desde el paso 1 al 4, hasta que finalice la Lista A O BIEN la Lista B.

1

Prueba esto:

public static void main(String[] args) {System.nanoTime() 
    List<A> as = new ArrayList<A>(); 
    List<B> bs = new ArrayList<B>(); 

    // Collect all A.ids in the list of B into a Set 
    Set<String> baids = new HashSet<String>(); 
    for (B b : bs) 
     baids.add(b.aid); 

    // iterate through the list of A discarding those that don't have a B 
    for (Iterator<A> i = as.iterator(); i.hasNext();) 
     if (!baids.contains(i.next().Id)) // contains() executes fast for a Set 
      i.remove(); 

    // now list "as" contains all A that have a B with A.Id = B.aid 
} 
+0

El resultado requerido es una * "lista de A con ubicación en B" *. ¿Cómo logra este algoritmo eso? – NPE

+0

pero estoy haciendo primero for loop para obtener ids de una lista, segundo para loop para obtener de la segunda lista y retener internamente todo también para loop y luego ejecutaré un ciclo for para obtener el objeto exacto. ¿Es posible que podamos hacer uso de objetos y reemplazar a iguales? –

+0

@aix (piensa omg ... ¿debo alimentar con cuchara?) Bien ... He añadido una línea más para mostrar cómo se soluciona el misterio de obtener una lista de un conjunto. – Bohemian

0

Uso de Java 8 arroyos

List<A> listA = new ArrayList<A>(); 
List<B> listB = new ArrayList<B>(); 

Set<Integer> aIdsFromBList = listB.stream().map(B::getAId).collect(Collectors.toSet()); 

return listA.stream 
    .filter(a -> aIdsFromBList.contains(a.getId())) 
    .collect(Collectors.toList()); 
Cuestiones relacionadas