web-dev-qa-db-fra.com

Comment puis-je calculer la différence entre deux ArrayLists?

J'ai deux ArrayLists.

ArrayList A contient

['2009-05-18','2009-05-19','2009-05-21']

ArrayList B contient ['2009-05-18','2009-05-18','2009-05-19','2009-05-19','2009-05-20','2009-05-21','2009-05-21','2009-05-22']

Je dois comparer ArrayLst A et ArrayLst B. Le résultat ArrayList doit contenir la liste qui n’existe pas dans ArrayList A. Le résultat ArrayList doit être

['2009-05-20', '2009-05-22']

comment comparer?

78
naveen

En Java, vous pouvez utiliser la méthode Collection de l'interface removeAll .

// Create a couple ArrayList objects and populate them
// with some delicious fruits.
Collection firstList = new ArrayList() {{
    add("Apple");
    add("orange");
}};

Collection secondList = new ArrayList() {{
    add("Apple");
    add("orange");
    add("banana");
    add("strawberry");
}};

// Show the "before" lists
System.out.println("First List: " + firstList);
System.out.println("Second List: " + secondList);

// Remove all elements in firstList from secondList
secondList.removeAll(firstList);

// Show the "after" list
System.out.println("Result: " + secondList);

Le code ci-dessus produira la sortie suivante:

First List: [Apple, orange]
Second List: [Apple, orange, banana, strawberry]
Result: [banana, strawberry]
187
William Brendel

Vous avez déjà la bonne réponse. Et si vous voulez faire des opérations plus compliquées et intéressantes entre les Listes (collections), utilisez Collections communes d'Apache ( CollectionUtils ) Il vous permet de faire des conjonctions/disjonctions, de trouver des intersections, de vérifier si une collection est un sous-ensemble d'une autre et d'autres belles choses.

20
andrii

Dans Java 8 avec des flux, c'est assez simple en fait.

List<String> listA = Arrays.asList("2009-05-18","2009-05-19","2009-05-21");
List<String> listB = Arrays.asList("2009-05-18","2009-05-18","2009-05-19","2009-05-19",
                                   "2009-05-20","2009-05-21","2009-05-21","2009-05-22");

List<String> result = listB.stream()
                           .filter(not(new HashSet<>(listA)::contains))
                           .collect(Collectors.toList());

Notez que le hachage n'est créé qu'une seule fois: la référence de la méthode est liée à sa méthode includes. Faire la même chose avec lambda nécessiterait d'avoir l'ensemble dans une variable. Faire une variable n'est pas une mauvaise idée, surtout si vous la trouvez inesthétique ou difficile à comprendre.

Vous ne pouvez pas facilement nier le prédicat sans utiliser cette méthode d'utilitaire (ou de transtypage explicite), car vous ne pouvez pas appeler directement la référence de la méthode negate (l'inférence de type est nécessaire en premier).

private static <T> Predicate<T> not(Predicate<T> predicate) {
    return predicate.negate();
}

Si les flux avaient une méthode filterOut ou quelque chose d'autre, cela aurait l'air plus joli.

12
Vlasec

EDIT: La question originale ne spécifiait pas la langue. Ma réponse est en C #.

Vous devriez plutôt utiliser HashSet à cette fin. Si vous devez utiliser ArrayList, vous pouvez utiliser les méthodes d'extension suivantes:

var a = arrayListA.Cast<DateTime>();
var b = arrayListB.Cast<DateTime>();    
var c = b.Except(a);

var arrayListC = new ArrayList(c.ToArray());

en utilisant HashSet ...

var a = new HashSet<DateTime>(); // ...and fill it
var b = new HashSet<DateTime>(); // ...and fill it
b.ExceptWith(a); // removes from b items that are in a
9
Josh

J'ai utilisé la goyave Sets.difference .

Les paramètres sont des ensembles et non des collections générales, mais un moyen pratique de créer des ensembles à partir de n'importe quelle collection (avec des éléments uniques) est Guava ImmutableSet.copyOf (Iterable).

(J'ai d'abord posté ceci sur une question liée/dupe , mais je le copie ici aussi car je pense que c'est une bonne option qui manque jusqu'à présent.)

8
Peter Lamberg

Bien que cette question soit très ancienne dans Java 8, vous pouvez faire quelque chose comme:

 List<String> a1 = Arrays.asList("2009-05-18", "2009-05-19", "2009-05-21");
 List<String> a2 = Arrays.asList("2009-05-18", "2009-05-18", "2009-05-19", "2009-05-19", "2009-05-20", "2009-05-21","2009-05-21", "2009-05-22");

 List<String> result = a2.stream().filter(elem -> !a1.contains(elem)).collect(Collectors.toList());
7
jesantana

Je suppose que vous parlez de C #. Si oui, vous pouvez essayer ceci

    ArrayList CompareArrayList(ArrayList a, ArrayList b)
    {
        ArrayList output = new ArrayList();
        for (int i = 0; i < a.Count; i++)
        {
            string str = (string)a[i];
            if (!b.Contains(str))
            {
                if(!output.Contains(str)) // check for dupes
                    output.Add(str);
            }
        }
        return output;
    }
2
Pavels

CE TRAVAIL AUSSI AVEC Arraylist

    // Create a couple ArrayList objects and populate them
    // with some delicious fruits.
    ArrayList<String> firstList = new ArrayList<String>() {/**
         * 
         */
        private static final long serialVersionUID = 1L;

    {
        add("Apple");
        add("orange");
        add("pea");
    }};

    ArrayList<String> secondList = new ArrayList<String>() {

    /**
         * 
         */
        private static final long serialVersionUID = 1L;

    {
        add("Apple");
        add("orange");
        add("banana");
        add("strawberry");
    }};

    // Show the "before" lists
    System.out.println("First List: " + firstList);
    System.out.println("Second List: " + secondList);

    // Remove all elements in firstList from secondList
    secondList.removeAll(firstList);

    // Show the "after" list
    System.out.println("Result: " + secondList);
1
psycho

Vous ne faites que comparer des chaînes.

Placez les valeurs dans ArrayList A en tant que clés dans HashTable A.
Placez les valeurs dans ArrayList B en tant que clés dans HashTable B.

Ensuite, pour chaque clé de HashTable A, supprimez-la de HashTable B si elle existe.

Ce qui vous reste dans HashTable B sont les chaînes (clés) qui n'étaient pas des valeurs dans ArrayList A.

Exemple C # (3.0) ajouté en réponse à la demande de code:

List<string> listA = new List<string>{"2009-05-18","2009-05-19","2009-05-21'"};
List<string> listB = new List<string>{"2009-05-18","2009-05-18","2009-05-19","2009-05-19","2009-05-20","2009-05-21","2009-05-21","2009-05-22"};

HashSet<string> hashA = new HashSet<string>();
HashSet<string> hashB = new HashSet<string>();

foreach (string dateStrA in listA) hashA.Add(dateStrA);
foreach (string dateStrB in listB) hashB.Add(dateStrB);

foreach (string dateStrA in hashA)
{
    if (hashB.Contains(dateStrA)) hashB.Remove(dateStrA);
}

List<string> result = hashB.ToList<string>();
1
Demi

Salut utiliser cette classe, cela va comparer les deux listes et montre exactement la différence entre les deux listes.

import Java.util.ArrayList;
import Java.util.List;


public class ListCompare {

    /**
     * @param args
     */
    public static void main(String[] args) {
        List<String> dbVinList;
        dbVinList = new ArrayList<String>();
        List<String> ediVinList;
        ediVinList = new ArrayList<String>();           

        dbVinList.add("A");
        dbVinList.add("B");
        dbVinList.add("C");
        dbVinList.add("D");

        ediVinList.add("A");
        ediVinList.add("C");
        ediVinList.add("E");
        ediVinList.add("F");
        /*ediVinList.add("G");
        ediVinList.add("H");
        ediVinList.add("I");
        ediVinList.add("J");*/  

        List<String> dbVinListClone = dbVinList;
        List<String> ediVinListClone = ediVinList;

        boolean flag;
        String mismatchVins = null;
        if(dbVinListClone.containsAll(ediVinListClone)){
            flag = dbVinListClone.removeAll(ediVinListClone);   
            if(flag){
                mismatchVins = getMismatchVins(dbVinListClone);
            }
        }else{
            flag = ediVinListClone.removeAll(dbVinListClone);
            if(flag){
                mismatchVins = getMismatchVins(ediVinListClone);
            }
        }
        if(mismatchVins != null){
            System.out.println("mismatch vins : "+mismatchVins);
        }       

    }

    private static String getMismatchVins(List<String> mismatchList){
        StringBuilder mismatchVins = new StringBuilder();
        int i = 0;
        for(String mismatch : mismatchList){
            i++;
            if(i < mismatchList.size() && i!=5){
                mismatchVins.append(mismatch).append(",");  
            }else{
                mismatchVins.append(mismatch);
            }
            if(i==5){               
                break;
            }
        }
        String mismatch1;
        if(mismatchVins.length() > 100){
            mismatch1 = mismatchVins.substring(0, 99);
        }else{
            mismatch1 = mismatchVins.toString();
        }       
        return mismatch1;
    }

}
1
Raj Mohamad