2010-05-04 29 views
74

tengo dos listas (no listas de Java, se puede decir dos columnas)Java comparar dos listas

Por ejemplo

**List 1**   **Lists 2** 
    milan     hafil 
    dingo     iga 
    iga     dingo 
    elpha     binga 
    hafil     mike 
    meat     dingo 
    milan 
    elpha 
    meat 
    iga     
    neeta.peeta  

me gustaría un método que devuelve el número de elementos son los mismos. Para este ejemplo, debe ser 3 y también me debe devolver valores similares de la lista y valores diferentes.

Debo usar hashmap en caso afirmativo, entonces, ¿qué método debo utilizar para obtener mi resultado?

Por favor, ayuda

PS: No es una tarea escolar :) Así que si sólo me guía será suficiente

+0

Para sugerir una estructura de datos de la lista no está lista java o HashMap o cualquier estructura de datos – user238384

+1

Asegúrese de pensar en lo que debe hacer en casos excepcionales. ¿Pueden las listas contener el mismo valor dos veces? Si es así, si "dingo" está en ambas listas dos veces, ¿eso cuenta como dos elementos en común o solo uno? – JavadocMD

+0

¿Se puede modificar uno de la lista? –

Respuesta

143

EDITAR

Aquí hay dos versiones. Una y otra utilizando ArrayList usando HashSet

compararlas y crear su propia versión de esto, hasta que se obtiene lo que necesita.

Esto debería ser suficiente para cubrir el:

PS: No es una tarea escolar :) Así que si sólo me guía será suficiente

parte de su pregunta .

continuar con la respuesta original:

Se puede usar un java.util.Collection y/o java.util.ArrayList para eso.

El método retainAll hace lo siguiente:

conserva solamente los elementos de esta colección que están contenidos en la colección especificada

ver este ejemplo:

import java.util.Collection; 
import java.util.ArrayList; 
import java.util.Arrays; 

public class Repeated { 
    public static void main(String [] args) { 
     Collection listOne = new ArrayList(Arrays.asList("milan","dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta")); 
     Collection listTwo = new ArrayList(Arrays.asList("hafil", "iga", "binga", "mike", "dingo")); 

     listOne.retainAll(listTwo); 
     System.out.println(listOne); 
    } 
} 

EDITAR

para la segunda parte (valores similares) puede usar la removeAll método:

Elimina todos los elementos de esta colección que también están contenidos en la colección especificada.

Esta segunda versión también le da los valores y asas similares repetidos (descartándolos).

Esta vez el Collection podría ser una Set en lugar de un List (valores de la diferencia es, el conjunto no permite repetir)

import java.util.Collection; 
import java.util.HashSet; 
import java.util.Arrays; 

class Repeated { 
     public static void main(String [] args) { 

      Collection<String> listOne = Arrays.asList("milan","iga", 
                "dingo","iga", 
                "elpha","iga", 
                "hafil","iga", 
                "meat","iga", 
                "neeta.peeta","iga"); 

      Collection<String> listTwo = Arrays.asList("hafil", 
                "iga", 
                "binga", 
                "mike", 
                "dingo","dingo","dingo"); 

      Collection<String> similar = new HashSet<String>(listOne); 
      Collection<String> different = new HashSet<String>(); 
      different.addAll(listOne); 
      different.addAll(listTwo); 

      similar.retainAll(listTwo); 
      different.removeAll(similar); 

      System.out.printf("One:%s%nTwo:%s%nSimilar:%s%nDifferent:%s%n", listOne, listTwo, similar, different); 
     } 
} 

Salida:

$ java Repeated 
One:[milan, iga, dingo, iga, elpha, iga, hafil, iga, meat, iga, neeta.peeta, iga] 

Two:[hafil, iga, binga, mike, dingo, dingo, dingo] 

Similar:[dingo, iga, hafil] 

Different:[mike, binga, milan, meat, elpha, neeta.peeta] 

Si no es así' Haga exactamente lo que necesita, le da un buen comienzo para que pueda manejar desde aquí.

Pregunta para el lector: ¿Cómo incluiría todos los valores repetidos?

+0

@Oscar, ¡Mi pensamiento exacto, pero no estaba seguro de si podríamos haber modificado el contenido de 'listOne', pero +1 de todos modos! –

+0

No debe usar tipos crudos. – polygenelubricants

+0

@poygenelubricants ¿a qué te refieres con * tipos crudos * no genéricos? Por qué no? – OscarRyz

1

Suponiendo hash1 y hash2

List<String> sames = whatever 
List<String> diffs = whatever 

int count = 0; 
for(String key : hash1.keySet()) 
{ 
    if(hash2.containsKey(key)) 
    { 
     sames.add(key); 
    } 
    else 
    { 
     diffs.add(key); 
    } 
} 

//sames.size() contains the number of similar elements. 
+0

Quiere la lista de claves idénticas, no cuántas teclas son idénticas. Creo. –

+0

Gracias Stefan por su ayuda. Sí, Rosdi tiene razón y tú también. Necesito el número total de valores similares y valores similares también. – user238384

8

Son estos realmente lists (ordenado, con duplicados), ¿o son sets (sin pedido, sin duplicados)?

Porque si es el último, entonces puede usar, por ejemplo, un java.util.HashSet<E> y hacer esto en el tiempo lineal esperado usando el conveniente retainAll.

List<String> list1 = Arrays.asList(
     "milan", "milan", "iga", "dingo", "milan" 
    ); 
    List<String> list2 = Arrays.asList(
     "hafil", "milan", "dingo", "meat" 
    ); 

    // intersection as set 
    Set<String> intersect = new HashSet<String>(list1); 
    intersect.retainAll(list2); 
    System.out.println(intersect.size()); // prints "2" 
    System.out.println(intersect); // prints "[milan, dingo]" 

    // intersection/union as list 
    List<String> intersectList = new ArrayList<String>(); 
    intersectList.addAll(list1); 
    intersectList.addAll(list2); 
    intersectList.retainAll(intersect); 
    System.out.println(intersectList); 
    // prints "[milan, milan, dingo, milan, milan, dingo]" 

    // original lists are structurally unmodified 
    System.out.println(list1); // prints "[milan, milan, iga, dingo, milan]" 
    System.out.println(list2); // prints "[hafil, milan, dingo, meat]" 
+0

bueno, realmente no sé qué estructura de datos debería ser. Tiene duplicados. Ahora puede ver la pregunta actualizada – user238384

+0

¿Eliminará los valores repetidos del conjunto de datos? Porque no quiero perder ningún valor :( – user238384

+0

@agazerboy: He intentado responder a ambas preguntas. Siéntanse libres de pedir más aclaraciones. – polygenelubricants

27

Puede probar intersection() y subtract() métodos de CollectionUtils.

método intersection() le da una colección que contiene elementos comunes y el método subtract() le ofrece todos los poco comunes.

También deben cuidar de elementos similares

+0

Esto funcionó perfecto para mí. Código mucho más fácil. – Zeus

1

me encontré con un ejemplo muy básico de la comparación de lista en List Compare En este ejemplo se verifica el tamaño primero y luego comprueba la disponibilidad del elemento particular de una lista en otra.

3

Utilización de Java 8 removeIf

public int getSimilarItems(){ 
    List<String> one = Arrays.asList("milan", "dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta"); 
    List<String> two = new ArrayList<>(Arrays.asList("hafil", "iga", "binga", "mike", "dingo")); //Cannot remove directly from array backed collection 
    int initial = two.size(); 

    two.removeIf(one::contains); 
    return initial - two.size(); 
} 
+0

Se ve bien, pero si quiero mantener las listas sin modificar tendría que clonar una de las listas y eso no sería deseado en ciertos casos. – sebadagostino

-1
public static boolean compareList(List ls1, List ls2){ 
    return ls1.containsAll(ls2) && ls1.size() == ls2.size() ? true :false; 
    } 

public static void main(String[] args) { 

    ArrayList<String> one = new ArrayList<String>(); 
    one.add("one"); 
    one.add("two"); 
    one.add("six"); 

    ArrayList<String> two = new ArrayList<String>(); 
    two.add("one"); 
    two.add("six"); 
    two.add("two"); 

    System.out.println("Output1 :: " + compareList(one, two)); 

    two.add("ten"); 

    System.out.println("Output2 :: " + compareList(one, two)); 
    } 
+0

Esta solución devuelve el resultado incorrecto cuando dos contiene 3 copias de "uno". Produciría incorrectamente un resultado verdadero. –