Java ArrayList - comment puis-je savoir si deux listes sont égales, l'ordre n'a pas d'importance?


133

J'ai deux ArrayLists de type Answer(classe self-made).

J'aimerais comparer les deux listes pour voir si elles contiennent le même contenu, mais sans ordre d'importance.

Exemple:

//These should be equal.
ArrayList<String> listA = {"a", "b", "c"}
ArrayList<String> listB = {"b", "c", "a"}

List.equalsindique que deux listes sont égales si elles contiennent la même taille, le même contenu et l'ordre des éléments. Je veux la même chose, mais sans ordre d'importance.

Existe-t-il un moyen simple de procéder? Ou aurai-je besoin de faire une boucle for imbriquée et de vérifier manuellement chaque index des deux listes?

Remarque: je ne peux pas les changer ArrayListpour un autre type de liste, ils doivent le rester.


4
voir la réponse à cette question: stackoverflow.com/a/1075699/1133011
David Kroukamp

Voir List.containsAll (list) en java
Sahil Jain

Réponses:


130

Vous pouvez trier les deux listes en utilisant Collections.sort(), puis utiliser la méthode d'égalité. Une solution légèrement meilleure consiste à vérifier d'abord si elles ont la même longueur avant de commander, si elles ne le sont pas, alors elles ne sont pas égales, puis trier, puis utiliser égales. Par exemple, si vous aviez deux listes de chaînes, ce serait quelque chose comme:

public  boolean equalLists(List<String> one, List<String> two){     
    if (one == null && two == null){
        return true;
    }

    if((one == null && two != null) 
      || one != null && two == null
      || one.size() != two.size()){
        return false;
    }

    //to avoid messing the order of the lists we will use a copy
    //as noted in comments by A. R. S.
    one = new ArrayList<String>(one); 
    two = new ArrayList<String>(two);   

    Collections.sort(one);
    Collections.sort(two);      
    return one.equals(two);
}

20
N'oubliez pas de ne pas détruire l'ordre de la liste d'origine (comme le Collections.sortfait) - c'est-à-dire de transmettre une copie.
arshajii

@ARS oui, c'est un effet secondaire certain, mais seulement si cela compte dans leur cas particulier.
Jacob Schoen

3
Vous pouvez simplement ajouter one = new ArrayList<String>(one); two = new ArrayList<String>(two);pour éviter de ruiner les arguments.
arshajii

@jschoen Essayer de faire Collections.sort () me donne cette erreur: Incohérence liée: La méthode générique sort (List <T>) de type Collections n'est pas applicable pour les arguments (ArrayList <Answer>). Le type inféré Answer n'est pas un substitut valide pour le paramètre borné <T extend Comparable <? super T >>
iaacp

3
La deuxième instruction "if" à l'intérieur de la fonction peut être simplifiée if(one == null || two == null || one.size() != two.size()){ return false; }car vous vérifiez déjà si un et deux sont nuls
Hugo

151

Le moyen le plus simple pour toute liste serait probablement:

listA.containsAll(listB) && listB.containsAll(listA)

5
Où est le plaisir là-dedans. Sérieusement, c'est probablement la meilleure solution.
Jacob Schoen

67
Cela dépend du fait que [a, b, c]et [c, b, a, b]sont considérés comme ayant le même contenu. Cette réponse dirait qu'ils le font, mais il se peut que pour l'OP ils ne le fassent pas (puisque l'un contient un doublon et l'autre pas). Pour ne rien dire des problèmes d'efficacité.
yshavit

4
amélioration basée sur les commentaires - System.out.println (((l1.size () == l2.size ()) && l2.containsAll (l1) && l1.containsAll (l2)));
Nrj

8
@Nrj, qu'en est-il de [1,2,2] et [2,1,1]?
ROMANIA_engineer

3
Cette approche a une complexité de O (n ^ 2). Considérons deux listes qui sont dans l'ordre inverse, par exemple: [1,2,3] et [3,2,1]. Pour le premier élément, il devra scanner n éléments, pour les seconds n-1 éléments et ainsi de suite. La complexité sera donc d'ordre n ^ 2. Je pense que la meilleure façon sera de trier puis d'utiliser des égaux. Il aura une complexité de O (n * log (n))
puneet

90

Apache Commons Collections à la rescousse une fois de plus:

List<String> listA = Arrays.asList("a", "b", "b", "c");
List<String> listB = Arrays.asList("b", "c", "a", "b");
System.out.println(CollectionUtils.isEqualCollection(listA, listB)); // true

 

List<String> listC = Arrays.asList("a", "b", "c");
List<String> listD = Arrays.asList("a", "b", "c", "c");
System.out.println(CollectionUtils.isEqualCollection(listC, listD)); // false

Documents:

org.apache.commons.collections4.CollectionUtils

public static boolean isEqualCollection(java.util.Collection a,
                                        java.util.Collection b)

Renvoie truessi les Collections donnés contiennent exactement les mêmes éléments avec exactement les mêmes cardinalités.

Autrement dit, si la cardinalité de e dans a est égale à la cardinalité de e dans b , pour chaque élément e dans a ou b .

Paramètres:

  • a - la première collection, ne doit pas être null
  • b - la deuxième collection, ne doit pas être null

Renvoie: truessi les collections contiennent les mêmes éléments avec les mêmes cardinalités.


La mise en œuvre semble plus ou moins similaire à la réponse de DiddiZ.
user227353

OK ... mais qu'en est-il de mettre la main sur les coupables (éléments qui ne sont pas communs aux deux listes) si la réponse est false? Voyez ma réponse.
mike rodent

implementation 'org.apache.commons:commons-collections4:4.3'm'a laissé un Caused by: com.android.builder.dexing.DexArchiveBuilderException: Failed to process chemin d' erreur .
Aliton Oliveira

13
// helper class, so we don't have to do a whole lot of autoboxing
private static class Count {
    public int count = 0;
}

public boolean haveSameElements(final List<String> list1, final List<String> list2) {
    // (list1, list1) is always true
    if (list1 == list2) return true;

    // If either list is null, or the lengths are not equal, they can't possibly match 
    if (list1 == null || list2 == null || list1.size() != list2.size())
        return false;

    // (switch the two checks above if (null, null) should return false)

    Map<String, Count> counts = new HashMap<>();

    // Count the items in list1
    for (String item : list1) {
        if (!counts.containsKey(item)) counts.put(item, new Count());
        counts.get(item).count += 1;
    }

    // Subtract the count of items in list2
    for (String item : list2) {
        // If the map doesn't contain the item here, then this item wasn't in list1
        if (!counts.containsKey(item)) return false;
        counts.get(item).count -= 1;
    }

    // If any count is nonzero at this point, then the two lists don't match
    for (Map.Entry<String, Count> entry : counts.entrySet()) {
        if (entry.getValue().count != 0) return false;
    }

    return true;
}

Wow, a été vraiment surpris de trouver cela plus rapide que toutes les autres solutions. Et il prend en charge la sortie anticipée.
DiddiZ

Cela pourrait également court-circuiter dans la deuxième boucle, si cela countdevient négatif, ce qui simplifie le corps de la if(!counts.containsKey(item) || --counts.get(item).count < 0) return false;boucle.En outre, la troisième boucle pourrait être simplifiée àfor(Count c: counts.values()) if(c.count != 0) return false;
Holger

@Holger J'avais envisagé quelque chose qui s'apparente au premier (supprimer le décompte lorsqu'il atteint zéro, ce qui aurait le même effet mais transformerait également les vérifications à la fin en "retourner si countsest vide"), mais je ne voulais pas obscurcir le point principal: que l'utilisation d'une carte transforme fondamentalement cela en un problème O (N + M), et c'est le plus gros coup de pouce que vous êtes susceptible d'obtenir.
cHao

@cHao oui, vous méritez les crédits pour avoir pointé vers une solution avec une meilleure complexité temporelle que les précédentes. J'y ai juste réfléchi, car il y a une question similaire récente concernant les itérables. Puisque nous avons également maintenant Java 8, cela valait la peine de le repenser. Si vous court-circuitez dans la deuxième boucle lorsque le nombre devient négatif, la troisième boucle devient obsolète. De plus, éviter la boxe pourrait être une arme à double tranchant, avec de nouveaux Map.merge, l'utilisation d'entiers encadrés pourrait être plus simple et plus efficace pour la plupart des cas d'utilisation. Voir aussi cette réponse
Holger

10

Je dirais que ces réponses manquent un truc.

Bloch, dans son essentiel, merveilleux et concis Effective Java , dit, au point 47, titre «Connaître et utiliser les bibliothèques», «Pour résumer, ne réinventez pas la roue». Et il donne plusieurs raisons très claires pourquoi pas.

Il y a quelques réponses ici qui suggèrent des méthodes de CollectionUtilsla bibliothèque Apache Commons Collections, mais aucune n'a repéré la manière la plus belle et la plus élégante de répondre à cette question :

Collection<Object> culprits = CollectionUtils.disjunction( list1, list2 );
if( ! culprits.isEmpty() ){
  // ... do something with the culprits, i.e. elements which are not common

}

Les coupables : c'est-à-dire les éléments qui ne sont pas communs aux deux Lists. Déterminer à quels coupables appartiennent list1et à qui list2est relativement simple en utilisant CollectionUtils.intersection( list1, culprits )et CollectionUtils.intersection( list2, culprits ).
Cependant, il a tendance à s'effondrer dans des cas comme {"a", "a", "b"} disjunctionavec {"a", "b", "b"} ... sauf que ce n'est pas un échec du logiciel, mais inhérente à la nature des subtilités / ambiguïtés de la tâche souhaitée.

Vous pouvez toujours examiner le code source (l. 287) pour une tâche comme celle-ci, tel que produit par les ingénieurs Apache. Un avantage de l'utilisation de leur code est qu'il aura été minutieusement essayé et testé, avec de nombreux cas extrêmes et des pièges anticipés et traités. Vous pouvez copier et modifier ce code à votre guise si nécessaire.


NB J'ai été au début déçu qu'aucune des CollectionUtilsméthodes ne propose une version surchargée vous permettant d'imposer la vôtre Comparator(afin que vous puissiez la redéfinir equalsen fonction de vos besoins).

Mais à partir de collections4 4.0, il existe une nouvelle classe, Equatorqui "détermine l'égalité entre les objets de type T". À l'examen du code source de collections4 CollectionUtils.java, ils semblent l'utiliser avec certaines méthodes, mais pour autant que je sache, cela ne s'applique pas aux méthodes en haut du fichier, en utilisant la CardinalityHelperclasse ... qui inclure disjunctionet intersection.

Je suppose que les gens d'Apache ne sont pas encore parvenus à cela parce que ce n'est pas trivial: vous devriez créer quelque chose comme une classe "AbstractEquatingCollection", qui au lieu d'utiliser les méthodes equalset les éléments inhérents à ses éléments hashCodede Equatorpour toutes les méthodes de base, tels que add, contains, etc. NB en fait , quand vous regardez le code source, AbstractCollectionne met pas en oeuvre add, ni ne les sous - classes abstraites telles que AbstractSet... vous devez attendre jusqu'à ce que les classes concrètes telles que HashSetet ArrayListavant addest implémenté. Un mal de tête.

En attendant, surveillez cet espace, je suppose. La solution provisoire évidente serait d'envelopper tous vos éléments dans une classe wrapper sur mesure qui utilise equalset hashCoded'implémenter le type d'égalité que vous souhaitez ... puis de manipuler Collectionsces objets wrapper.


Aussi, quelqu'un de sage a dit "Connaître le coût de la dépendance"
Stanislaw Baranski

@StanislawBaranski C'est un commentaire intéressant. Est-ce une suggestion qu'il ne faut pas trop dépendre de telles bibliothèques? Lorsque vous utilisez un système d'exploitation sur un ordinateur, c'est déjà un énorme acte de foi, n'est-ce pas? La raison pour laquelle je suis heureux d'utiliser les bibliothèques Apache est parce que je les considère comme de très haute qualité, et suppose que leurs méthodes sont conformes à leur «contrat» et ont été minutieusement testées. Combien de temps prendriez-vous pour développer votre propre code auquel vous faites plus confiance? Copier le code des bibliothèques Apache open-source et l'examiner attentivement pourrait être quelque chose à penser ...
mike rodent

8

Si la cardinalité des éléments n'a pas d'importance (c'est-à-dire que les éléments répétés sont considérés comme un), il existe un moyen de le faire sans avoir à trier:

boolean result = new HashSet<>(listA).equals(new HashSet<>(listB));

Cela créera un Sethors de chacun List, puis utilisera HashSetla equalsméthode de qui (bien sûr) ne tient pas compte de l'ordre.

Si la cardinalité compte, vous devez vous limiter aux installations fournies par List; La réponse de @ jschoen serait plus appropriée dans ce cas.


et si listA = [a, b, c, c] et listB = [a, b, c]. le résultat sera vrai, mais les listes ne sont pas égales.
Nikolas

6

La conversion des listes en Multiset de Guava fonctionne très bien. Ils sont comparés quel que soit leur ordre et les éléments en double sont également pris en compte.

static <T> boolean equalsIgnoreOrder(List<T> a, List<T> b) {
    return ImmutableMultiset.copyOf(a).equals(ImmutableMultiset.copyOf(b));
}

assert equalsIgnoreOrder(ImmutableList.of(3, 1, 2), ImmutableList.of(2, 1, 3));
assert !equalsIgnoreOrder(ImmutableList.of(1), ImmutableList.of(1, 1));

6

Ceci est basé sur la solution @cHao. J'ai inclus plusieurs correctifs et améliorations de performances. Cela fonctionne environ deux fois plus vite que la solution de copie ordonnée égale. Fonctionne pour tout type de collection. Les collections vides et nulles sont considérées comme égales. Utilisez à votre avantage;)

/**
 * Returns if both {@link Collection Collections} contains the same elements, in the same quantities, regardless of order and collection type.
 * <p>
 * Empty collections and {@code null} are regarded as equal.
 */
public static <T> boolean haveSameElements(Collection<T> col1, Collection<T> col2) {
    if (col1 == col2)
        return true;

    // If either list is null, return whether the other is empty
    if (col1 == null)
        return col2.isEmpty();
    if (col2 == null)
        return col1.isEmpty();

    // If lengths are not equal, they can't possibly match
    if (col1.size() != col2.size())
        return false;

    // Helper class, so we don't have to do a whole lot of autoboxing
    class Count
    {
        // Initialize as 1, as we would increment it anyway
        public int count = 1;
    }

    final Map<T, Count> counts = new HashMap<>();

    // Count the items in col1
    for (final T item : col1) {
        final Count count = counts.get(item);
        if (count != null)
            count.count++;
        else
            // If the map doesn't contain the item, put a new count
            counts.put(item, new Count());
    }

    // Subtract the count of items in col2
    for (final T item : col2) {
        final Count count = counts.get(item);
        // If the map doesn't contain the item, or the count is already reduced to 0, the lists are unequal 
        if (count == null || count.count == 0)
            return false;
        count.count--;
    }

    // At this point, both collections are equal.
    // Both have the same length, and for any counter to be unequal to zero, there would have to be an element in col2 which is not in col1, but this is checked in the second loop, as @holger pointed out.
    return true;
}

Vous pouvez ignorer la dernière boucle for en utilisant un compteur de somme. Le compteur de somme comptera le total des comptes à chaque étape. Augmentez le compteur de somme dans la première boucle for et diminuez-le dans la deuxième boucle for. Si le compteur de somme est supérieur à 0, les listes ne correspondent pas, sinon c'est le cas. Actuellement, dans la boucle for finale, vous vérifiez si tous les comptes sont égaux à zéro ou en d'autres termes, si la somme de tous les comptes est égale à zéro. L'utilisation du type de compteur de somme annule cette vérification et renvoie true si le total des comptes est égal à zéro, ou false dans le cas contraire.
Sam

OMI, il vaut la peine de sauter cette boucle for car lorsque les listes correspondent (scénario du pire des cas), la boucle for ajoute un autre O (n) inutile.
Sam

@SatA en fait, vous pouvez supprimer la 3e boucle sans aucun remplacement. La deuxième boucle est déjà renvoyée falselorsqu'une clé n'existe pas ou que son compte devient négatif. Étant donné que la taille totale des deux listes correspond (cela a été vérifié au départ), il est impossible d'avoir des valeurs non nulles après la deuxième boucle, car il ne peut pas y avoir de valeurs positives pour une clé sans valeurs négatives pour une autre clé.
Holger

@holger, il semble que vous avez tout à fait raison. Pour autant que je sache, la 3e boucle n'est pas du tout nécessaire.
SatA

@SatA… et avec Java 8, cela peut être implémenté de manière concise, comme dans cette réponse .
Holger

5

Pensez à la façon dont vous feriez cela vous-même, sans ordinateur ou langage de programmation. Je vous donne deux listes d'éléments, et vous devez me dire si elles contiennent les mêmes éléments. Comment feriez-vous cela?

Une approche, comme mentionné ci-dessus, consiste à trier les listes, puis à aller élément par élément pour voir si elles sont égales (ce qui List.equals cas). Cela signifie que vous êtes autorisé à modifier les listes ou que vous êtes autorisé à les copier - et sans connaître l'affectation, je ne peux pas savoir si l'une ou les deux sont autorisées.

Une autre approche consisterait à parcourir chaque liste, en comptant le nombre de fois où chaque élément apparaît. Si les deux listes ont les mêmes nombres à la fin, elles ont les mêmes éléments. Le code pour cela serait de traduire chaque liste en une carte elem -> (# of times the elem appears in the list), puis d'appeler equalsles deux cartes. Si les cartes le sont HashMap, chacune de ces traductions est une opération O (N), tout comme la comparaison. Cela va vous donner un algorithme assez efficace en termes de temps, au prix d'un peu de mémoire supplémentaire.


5

J'ai eu le même problème et j'ai trouvé une solution différente. Celui-ci fonctionne également lorsque des doublons sont impliqués:

public static boolean equalsWithoutOrder(List<?> fst, List<?> snd){
  if(fst != null && snd != null){
    if(fst.size() == snd.size()){
      // create copied lists so the original list is not modified
      List<?> cfst = new ArrayList<Object>(fst);
      List<?> csnd = new ArrayList<Object>(snd);

      Iterator<?> ifst = cfst.iterator();
      boolean foundEqualObject;
      while( ifst.hasNext() ){
        Iterator<?> isnd = csnd.iterator();
        foundEqualObject = false;
        while( isnd.hasNext() ){
          if( ifst.next().equals(isnd.next()) ){
            ifst.remove();
            isnd.remove();
            foundEqualObject = true;
            break;
          }
        }

        if( !foundEqualObject ){
          // fail early
          break;
        }
      }
      if(cfst.isEmpty()){ //both temporary lists have the same size
        return true;
      }
    }
  }else if( fst == null && snd == null ){
    return true;
  }
  return false;
}

Avantages par rapport à certaines autres solutions:

  • complexité inférieure à O (N²) (même si je n'ai pas testé ses performances réelles par rapport aux solutions dans d'autres réponses ici);
  • sort tôt;
  • vérifie la valeur nulle;
  • fonctionne même lorsque des doublons sont impliqués: si vous avez un tableau [1,2,3,3]et un autre tableau, la [1,2,2,3]plupart des solutions ici vous indiquent qu'ils sont les mêmes si vous ne considérez pas l'ordre. Cette solution évite cela en supprimant les éléments égaux des listes temporaires;
  • utilise l'égalité sémantique ( equals) et non l'égalité de référence ( ==);
  • ne trie pas les itens, ils n'ont donc pas besoin d'être triables (par implement Comparable) pour que cette solution fonctionne.

3

Si vous n'espérez pas trier les collections et que vous avez besoin du résultat que ["A" "B" "C"] n'est pas égal à ["B" "B" "A" "C"],

l1.containsAll(l2)&&l2.containsAll(l1)

n'est pas suffisant, vous devez probablement vérifier la taille aussi:

    List<String> l1 =Arrays.asList("A","A","B","C");
    List<String> l2 =Arrays.asList("A","B","C");
    List<String> l3 =Arrays.asList("A","B","C");

    System.out.println(l1.containsAll(l2)&&l2.containsAll(l1));//cautions, this will be true
    System.out.println(isListEqualsWithoutOrder(l1,l2));//false as expected

    System.out.println(l3.containsAll(l2)&&l2.containsAll(l3));//true as expected
    System.out.println(isListEqualsWithoutOrder(l2,l3));//true as expected


    public static boolean isListEqualsWithoutOrder(List<String> l1, List<String> l2) {
        return l1.size()==l2.size() && l1.containsAll(l2)&&l2.containsAll(l1);
}

2

Solution qui exploite la méthode de soustraction de CollectionUtils:

import static org.apache.commons.collections15.CollectionUtils.subtract;

public class CollectionUtils {
  static public <T> boolean equals(Collection<? extends T> a, Collection<? extends T> b) {
    if (a == null && b == null)
      return true;
    if (a == null || b == null || a.size() != b.size())
      return false;
    return subtract(a, b).size() == 0 && subtract(a, b).size() == 0;
  }
}

1

Si vous vous souciez de la commande, utilisez simplement la méthode égale:

list1.equals(list2)

Si vous ne vous souciez pas de la commande, utilisez ceci

Collections.sort(list1);
Collections.sort(list2);      
list1.equals(list2)

4
Il dit qu'il ne se soucie pas de l'ordre.
mike rodent

0

Le meilleur des deux mondes [@DiddiZ, @Chalkos]: celui-ci s'appuie principalement sur la méthode @Chalkos, mais corrige un bogue (ifst.next ()), améliore les vérifications initiales (tirées de @DiddiZ) et supprime le besoin de copier la première collection (supprime simplement les éléments d'une copie de la deuxième collection).

Ne nécessitant pas de fonction de hachage ou de tri, et permettant une existence précoce sur l'inégalité, c'est l'implémentation la plus efficace à ce jour. À moins que vous n'ayez une longueur de collection de plusieurs milliers ou plus, et une fonction de hachage très simple.

public static <T> boolean isCollectionMatch(Collection<T> one, Collection<T> two) {
    if (one == two)
        return true;

    // If either list is null, return whether the other is empty
    if (one == null)
        return two.isEmpty();
    if (two == null)
        return one.isEmpty();

    // If lengths are not equal, they can't possibly match
    if (one.size() != two.size())
        return false;

    // copy the second list, so it can be modified
    final List<T> ctwo = new ArrayList<>(two);

    for (T itm : one) {
        Iterator<T> it = ctwo.iterator();
        boolean gotEq = false;
        while (it.hasNext()) {
            if (itm.equals(it.next())) {
                it.remove();
                gotEq = true;
                break;
            }
        }
        if (!gotEq) return false;
    }
    // All elements in one were found in two, and they're the same size.
    return true;
}

Si je ne me trompe pas, la complexité de cet algorithme dans un scénario valable (où les listes sont égales mais triées de manière opposée) serait O (N * N!).
SatA

En fait, ce serait O (N * (N / 2)), comme à chaque itération, la taille du tableau diminue.
jazzgil

0

C'est un moyen alternatif de vérifier l'égalité des listes de tableaux qui peuvent contenir des valeurs nulles:

List listA = Arrays.asList(null, "b", "c");
List listB = Arrays.asList("b", "c", null);

System.out.println(checkEquality(listA, listB)); // will return TRUE


private List<String> getSortedArrayList(List<String> arrayList)
{
    String[] array = arrayList.toArray(new String[arrayList.size()]);

    Arrays.sort(array, new Comparator<String>()
    {
        @Override
        public int compare(String o1, String o2)
        {
            if (o1 == null && o2 == null)
            {
                return 0;
            }
            if (o1 == null)
            {
                return 1;
            }
            if (o2 == null)
            {
                return -1;
            }
            return o1.compareTo(o2);
        }
    });

    return new ArrayList(Arrays.asList(array));
}

private Boolean checkEquality(List<String> listA, List<String> listB)
{
    listA = getSortedArrayList(listA);
    listB = getSortedArrayList(listB);

    String[] arrayA = listA.toArray(new String[listA.size()]);
    String[] arrayB = listB.toArray(new String[listB.size()]);

    return Arrays.deepEquals(arrayA, arrayB);
}

Quel est l'intérêt de toute cette copie entre listes et tableaux?
Holger

0

Ma solution pour cela. Ce n'est pas si cool, mais ça marche bien.

public static boolean isEqualCollection(List<?> a, List<?> b) {

    if (a == null || b == null) {
        throw new NullPointerException("The list a and b must be not null.");
    }

    if (a.size() != b.size()) {
        return false;
    }

    List<?> bCopy = new ArrayList<Object>(b);

    for (int i = 0; i < a.size(); i++) {

        for (int j = 0; j < bCopy.size(); j++) {
            if (a.get(i).equals(bCopy.get(j))) {
                bCopy.remove(j);
                break;
            }
        }
    }

    return bCopy.isEmpty();
}

-1

Dans ce cas, les listes {"a", "b"} et {"b", "a"} sont égales. Et {"a", "b"} et {"b", "a", "c"} ne sont pas égaux. Si vous utilisez une liste d'objets complexes, n'oubliez pas de remplacer la méthode equals , car containsAll l' utilise à l'intérieur.

if (oneList.size() == secondList.size() && oneList.containsAll(secondList)){
        areEqual = true;
}

-1: donne la mauvaise réponse avec {"a", "a", "b"} et {"a", "b", "b"}: vérifier le code source pour AbstractCollection.containsAll(). Vous devez permettre d'avoir des éléments en double dont nous parlons Lists, pas de Sets. S'il vous plaît voir ma réponse.
mike rodent
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.