Java ArrayList: come posso sapere se due elenchi sono uguali, l'ordine non ha importanza?


133

Ho due ArrayLists di tipo Answer(classe self-made).

Vorrei confrontare i due elenchi per vedere se contengono gli stessi contenuti, ma senza importanza per l'ordine.

Esempio:

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

List.equalsafferma che due elenchi sono uguali se contengono la stessa dimensione, contenuto e ordine degli elementi. Voglio la stessa cosa, ma senza ordine importa.

C'è un modo semplice per fare questo? O dovrò fare un ciclo nidificato per e controllare manualmente ogni indice di entrambi gli elenchi?

Nota: non posso cambiarli da ArrayListun altro tipo di elenco, devono rimanere tale.


4
vedere la risposta per questa domanda: stackoverflow.com/a/1075699/1133011
David Kroukamp

Vedi List.containsAll (elenco) in java
Sahil Jain

Risposte:


130

È possibile ordinare entrambi gli elenchi utilizzando Collections.sort()e quindi utilizzare il metodo equals. Una soluzione leggermente migliore è prima verificare se hanno la stessa lunghezza prima di ordinare, se non lo sono, allora non sono uguali, quindi ordinare, quindi utilizzare uguale. Ad esempio se avessi due elenchi di stringhe sarebbe qualcosa del tipo:

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
Ricorda solo di non distruggere l'ordine dell'elenco originale (come Collections.sortfa), ovvero passare una copia.
Arshajii,

@ARS sì, questo è un effetto collaterale definito, ma solo se è importante nel loro caso particolare.
Jacob Schoen,

3
Potresti semplicemente aggiungere one = new ArrayList<String>(one); two = new ArrayList<String>(two);per evitare di rovinare gli argomenti.
Arshajii,

@jschoen Tentativo di eseguire Collections.sort () mi dà questo errore: Mancata corrispondenza associata: l'ordinamento del metodo generico (Elenco <T>) del tipo Collezioni non è applicabile per gli argomenti (ArrayList <Risposta>). Il tipo inferito Answer non è un sostituto valido del parametro limitato <T extends Comparable <? super T >>
iaacp,

3
La seconda istruzione "if" all'interno della funzione può essere semplificata if(one == null || two == null || one.size() != two.size()){ return false; }perché si sta già verificando se sia uno che due sono nulli
Hugo,

151

Probabilmente il modo più semplice per qualsiasi elenco sarebbe:

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

5
Dov'è il divertimento in questo. In tutta serietà, questa è probabilmente la soluzione migliore.
Jacob Schoen,

67
Dipende se [a, b, c]e [c, b, a, b]si ritiene che abbiano gli stessi contenuti. Questa risposta direbbe di sì, ma potrebbe essere che per l'OP non lo facciano (poiché uno contiene un duplicato e l'altro no). Per non parlare dei problemi di efficienza.
yshavit,

4
miglioramento basato sui commenti - System.out.println ((((l1.size () == l2.size ()) && l2.containsAll (l1) && l1.containsAll (l2)));
Nrj

8
@Nrj, che dire di [1,2,2] e [2,1,1]?
ROMANIA_engineer,

3
Questo approccio ha complessità di O (n ^ 2). Considera due elenchi che sono in ordine inverso, ad esempio: [1,2,3] e [3,2,1]. Per il primo elemento dovrà scansionare n elementi, per i secondi n-1 elementi e così via. Quindi la complessità sarà dell'ordine n ^ 2. Penso che il modo migliore sarà quello di ordinare e quindi usare uguali. Avrà complessità di O (n * log (n))
puneet

90

Le raccolte di Apache Commons in soccorso ancora una volta:

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

Documenti:

org.apache.commons.collections4.CollectionUtils

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

Restituisce truese i dati specificati Collectioncontengono esattamente gli stessi elementi con esattamente le stesse cardinalità.

Cioè, se la cardinalità di e in a è uguale alla cardinalità di e in b , per ciascun elemento e in a o b .

parametri:

  • a - la prima collezione, non deve essere null
  • b - la seconda raccolta, non deve essere null

Restituisce: truese le raccolte contengono gli stessi elementi con le stesse cardinalità.


L'implementazione sembra più o meno simile con la risposta di DiddiZ.
user227353,

OK ... ma che dire di procurarsi i colpevoli (elementi che non sono comuni alle due liste) se la risposta è false? Vedi la mia risposta
mike rodent,

implementation 'org.apache.commons:commons-collections4:4.3'mi ha lasciato un Caused by: com.android.builder.dexing.DexArchiveBuilderException: Failed to process percorso di errore .
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, sono stato davvero sorpreso di trovare questa performance più veloce di tutte le altre soluzioni. E supporta early-out.
DiddiZ,

Questo potrebbe anche cortocircuitare nel secondo loop, se countdiventa negativo, semplificando il corpo del loop a if(!counts.containsKey(item) || --counts.get(item).count < 0) return false;Inoltre, il 3 ° loop potrebbe essere semplificato afor(Count c: counts.values()) if(c.count != 0) return false;
Holger

@Holger Avevo considerato qualcosa di simile al primo (rimuovendo il conteggio quando raggiunge lo zero, che avrebbe lo stesso effetto ma trasformerebbe anche i controlli alla fine in "restituisci se countsè vuoto"), ma non volevo oscurare il punto principale: l'uso di una mappa in pratica lo trasforma in un problema O (N + M), ed è la spinta più grande che potresti ottenere.
cHao,

@cHao sì, ti meriti i crediti per aver indicato una soluzione con una complessità temporale migliore rispetto alle precedenti. Mi è capitato di pensarci, perché c'è una domanda simile recente riguardo agli iterabili. Dato che ora abbiamo anche Java 8, valeva la pena ripensarlo. Se si esegue un cortocircuito nel secondo loop quando il numero diventa negativo, il terzo loop diventa obsoleto. Inoltre, evitare la boxe potrebbe essere un'arma a doppio taglio, con i nuovi Map.merge, l'utilizzo di numeri interi boxati potrebbe essere più semplice ed efficiente per la maggior parte dei casi d'uso. Vedi anche questa risposta ...
Holger,

10

Direi che a queste risposte manca un trucco.

Bloch, nel suo essenziale, meraviglioso, conciso Effective Java , dice, al punto 47, il titolo "Conosci e usa le librerie", "Per riassumere, non reinventare la ruota". E fornisce diverse ragioni molto chiare perché no.

Ci sono alcune risposte qui che suggeriscono metodi CollectionUtilsnella libreria delle Collezioni di Apache Commons, ma nessuna ha individuato il modo più bello ed elegante per rispondere a questa domanda :

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

}

Culprits : cioè gli elementi che non sono comuni ad entrambi Lists. Determinare a quali colpevoli appartengono list1e a quali list2è relativamente semplice usando CollectionUtils.intersection( list1, culprits )e CollectionUtils.intersection( list2, culprits ).
Tuttavia tende a sfaldarsi in casi come {"a", "a", "b"} disjunctioncon {"a", "b", "b"} ... tranne per il fatto che non si tratta di un errore del software, ma inerente alla natura delle sottigliezze / ambiguità dell'attività desiderata.

Puoi sempre esaminare il codice sorgente (l. 287) per un'attività come questa, prodotta dagli ingegneri Apache. Uno dei vantaggi dell'utilizzo del loro codice è che sarà stato accuratamente testato e testato, con molti casi limite e aspetti previsti e trattati. Puoi copiare e modificare questo codice in base al tuo cuore, se necessario.


NB All'inizio ero deluso dal fatto che nessuno dei CollectionUtilsmetodi fornisse una versione sovraccarica che ti consentisse di imporre il tuo Comparator(in modo da poter ridefinire equalsin base ai tuoi scopi).

Ma da collection4 4.0 esiste una nuova classe, Equatorche "determina l'uguaglianza tra oggetti di tipo T". Esaminando il codice sorgente di collection4 CollectionUtils.java sembrano usarlo con alcuni metodi, ma per quanto ne so non è applicabile ai metodi nella parte superiore del file, usando la CardinalityHelperclasse ... che include disjunctione intersection.

Suppongo che la gente di Apache non si sia ancora occupata di questo perché non è banale: dovresti creare qualcosa di simile a una classe "AbstractEquatingCollection", che invece di usare i suoi elementi intrinseci equalse i hashCodemetodi dovrebbero invece usare quelli di Equatorper tutti i metodi di base, come add, containsecc. NB, infatti, quando si guarda il codice sorgente, AbstractCollectionnon si implementa add, né si fanno le sue sottoclassi astratte come AbstractSet... bisogna aspettare fino alle classi concrete come HashSete ArrayListprima addè implementato. Abbastanza mal di testa.

Nel frattempo, guarda questo spazio, suppongo. L'ovvia soluzione provvisoria sarebbe quella di avvolgere tutti i tuoi elementi in una classe wrapper su misura che utilizza equalse hashCodeimplementare il tipo di uguaglianza che desideri ... quindi manipolare Collectionsquesti oggetti wrapper.


Inoltre, qualcuno di saggio ha detto "Conosci il costo della dipendenza"
Stanislaw Baranski il

@StanislawBaranski Questo è un commento interessante. È un suggerimento che non si dovrebbe dipendere troppo da tali biblioteche? Quando si utilizza un sistema operativo su un computer che è già un enorme salto di fiducia, non è vero? Il motivo per cui sono felice di usare le librerie Apache è perché le considero davvero di altissima qualità e presumo che i loro metodi siano conformi al loro "contratto" e siano stati accuratamente testati. Quanto tempo impiegheresti a sviluppare il tuo codice di cui ti fidavi di più? Copiare il codice dalle librerie Apache open source e scrutarlo potrebbe essere qualcosa a cui pensare ...
mike rodent,

8

Se la cardinalità degli oggetti non ha importanza (significato: gli elementi ripetuti sono considerati come uno), allora c'è un modo per farlo senza dover ordinare:

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

Questo creerà un Setfuori di ciascuno Liste quindi utilizzerà HashSetil equalsmetodo che (ovviamente) non tiene conto dell'ordinamento.

Se la cardinalità è importante, è necessario limitarsi alle strutture fornite da List; La risposta di @ jschoen sarebbe più adatta in quel caso.


cosa succede se listA = [a, b, c, c] e listB = [a, b, c]. il risultato sarà vero, ma le liste non sono uguali.
Nikolas,

6

La conversione delle liste in Multiset di Guava funziona molto bene. Vengono confrontati indipendentemente dal loro ordine e vengono presi in considerazione anche gli elementi duplicati.

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

Questo si basa sulla soluzione @cHao. Ho incluso diverse correzioni e miglioramenti delle prestazioni. Questo funziona all'incirca il doppio della soluzione uguale a copia ordinata. Funziona con qualsiasi tipo di raccolta. Le raccolte vuote e null sono considerate uguali. Usa a tuo vantaggio;)

/**
 * 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;
}

Puoi saltare il ciclo finale usando un contatore di somme. Il contatore delle somme conterà il totale dei conteggi in ogni fase. Aumenta il contatore della somma nel primo for-loop e diminuiscilo nel secondo for-loop. Se il contatore della somma è maggiore di 0, le liste non corrispondono, altrimenti lo fanno. Attualmente, nel for-loop finale controlli se tutti i conteggi sono zero o in altre parole, se la somma di tutti i conteggi è zero. L'utilizzo del tipo di contatore di somma inverte questo controllo, restituendo vero se il totale dei conteggi è zero o falso altrimenti.
SatA

IMO, vale la pena saltare quel for-loop poiché quando gli elenchi corrispondono (scenario peggiore) il for-loop aggiunge un'altra O (n) non necessaria.
SatA

@SatA in realtà, è possibile rimuovere il terzo ciclo senza alcuna sostituzione. Il secondo ciclo ritorna già falsequando non esiste una chiave o il suo conteggio diventa negativo. Poiché le dimensioni totali di entrambi gli elenchi corrispondono (questo è stato verificato in anticipo), è impossibile avere valori diversi da zero dopo il secondo ciclo, poiché non possono esserci valori positivi per una chiave senza valori negativi per un'altra chiave.
Holger,

@holger sembra che tu abbia assolutamente ragione. Per quanto ne so, il terzo ciclo non è affatto necessario.
SabA

@SatA… e con Java 8, questo può essere implementato in modo conciso, come in questa risposta .
Holger,

5

Pensa a come faresti da solo, in assenza di un computer o di un linguaggio di programmazione. Ti do due elenchi di elementi e devi dirmi se contengono gli stessi elementi. Come lo faresti?

Un approccio, come menzionato sopra, è quello di ordinare le liste e quindi andare elemento per elemento per vedere se sono uguali (che è ciò che List.equalsfa). Ciò significa che puoi modificare gli elenchi o copiarli e, senza conoscere il compito, non posso sapere se uno / entrambi sono ammessi.

Un altro approccio sarebbe quello di passare attraverso ogni elenco, contando quante volte appare ogni elemento. Se entrambi gli elenchi hanno gli stessi conteggi alla fine, hanno gli stessi elementi. Il codice sarebbe quello di tradurre ogni elenco in una mappa di elem -> (# of times the elem appears in the list)e quindi chiamare equalsle due mappe. Se le mappe lo sono HashMap, ognuna di queste traduzioni è un'operazione O (N), così come il confronto. Ti fornirà un algoritmo piuttosto efficiente in termini di tempo, al costo di un po 'di memoria aggiuntiva.


5

Ho avuto lo stesso problema e ho trovato una soluzione diversa. Questo funziona anche quando sono coinvolti duplicati:

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;
}

Vantaggi rispetto ad alcune altre soluzioni:

  • minore della complessità O (N²) (anche se non ho testato le sue prestazioni reali rispetto alle soluzioni in altre risposte qui);
  • esce presto;
  • controlla null;
  • funziona anche quando sono coinvolti duplicati: se hai un array [1,2,3,3]e un altro array, la [1,2,2,3]maggior parte delle soluzioni qui ti dicono che sono le stesse quando non consideri l'ordine. Questa soluzione evita questo rimuovendo elementi uguali dagli elenchi temporanei;
  • usa l'uguaglianza semantica ( equals) e non l'uguaglianza di riferimento ( ==);
  • non ordina gli iten, quindi non devono essere ordinabili (da implement Comparable) per far funzionare questa soluzione.

3

Se non speri di ordinare le raccolte e hai bisogno del risultato che ["A" "B" "C"] non è uguale a ["B" "B" "A" "C"],

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

non è abbastanza, è necessario controllare anche le dimensioni:

    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

Soluzione che sfrutta il metodo di sottrazione di 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

Se ti interessa l'ordine, usa semplicemente il metodo equals:

list1.equals(list2)

Se non ti interessa l'ordine, usa questo

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

4
Dice che non gli interessa l'ordine.
mike rodent,

0

Il meglio dei due mondi [@DiddiZ, @Chalkos]: questo si basa principalmente sul metodo @Chalkos, ma corregge un bug (ifst.next ()) e migliora i controlli iniziali (presi da @DiddiZ) e rimuove la necessità di copia la prima raccolta (rimuove solo gli elementi da una copia della seconda raccolta).

Non richiedendo una funzione di hashing o ordinamento e abilitando una precoce disuguaglianza, questa è l'implementazione più efficiente di sempre. Questo a meno che tu non abbia una lunghezza della raccolta in migliaia o più e una funzione di hashing molto semplice.

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;
}

Se non sbaglio, la complessità di questo algoritmo in uno scenario di valore (in cui gli elenchi sono uguali ma ordinati in modo opposto) sarebbe O (N * N!).
Sabato

In realtà, sarebbe O (N * (N / 2)), come ad ogni iterazione, la dimensione dell'array diminuisce.
jazzgil,

0

È un modo alternativo per verificare l'uguaglianza degli elenchi di array che può contenere valori null:

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);
}

Qual è il punto di tutto questo copiare tra elenchi e array?
Holger,

0

La mia soluzione per questo. Non è così bello, ma funziona bene.

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

In tal caso gli elenchi {"a", "b"} e {"b", "a"} sono uguali. E {"a", "b"} e {"b", "a", "c"} non sono uguali. Se usi un elenco di oggetti complessi, ricorda di sovrascrivere il metodo equals , poiché contieneAll lo usa all'interno.

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

-1: fornisce la risposta errata con {"a", "a", "b"} e {"a", "b", "b"}: controlla il codice sorgente per AbstractCollection.containsAll(). Devi consentire di avere elementi duplicati di cui stiamo parlando Lists, non di Sets. Si prega di vedere la mia risposta.
mike rodent,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.