web-dev-qa-db-fra.com

Quelle est la différence entre ArrayList.clear () et ArrayList.removeAll ()?

En supposant que arraylist soit défini comme ArrayList<String> arraylist, est arraylist.removeAll(arraylist) équivalent à arraylist.clear() ?

Si tel est le cas, puis-je supposer que la méthode clear() est plus efficace pour vider la liste de tableaux?

Y a-t-il des inconvénients à utiliser arraylist.removeAll(arraylist) au lieu de arraylist.clear()?

264
ateiob

Le code source de clear():

public void clear() {
    modCount++;

    // Let gc do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;

    size = 0;
}

Le code source de removeAll() (tel que défini dans AbstractCollection):

public boolean removeAll(Collection<?> c) {
    boolean modified = false;
    Iterator<?> e = iterator();
    while (e.hasNext()) {
        if (c.contains(e.next())) {
            e.remove();
            modified = true;
        }
    }
    return modified;
}

clear() est beaucoup plus rapide car il n'a pas à traiter tous ces appels de méthode supplémentaires.

Et comme le souligne Atrey, c.contains(..) augmente la complexité temporelle de removeAll à O (n ^ 2) par opposition à clear's O (n).

371
Jeffrey

La complexité temporelle de ArrayList.clear() est O(n) et de removeAll est O(n^2).

Alors oui, ArrayList.clear est beaucoup plus rapide.

46
Geoff

La méthode clear() supprime tous les éléments d'un seul ArrayList. C'est une opération rapide, car elle définit simplement certains éléments de tableau sur null.

La méthode removeAll(Collection), héritée de AbstractCollection, supprime tous les éléments de la collection d'arguments de la collection sur laquelle vous appelez la méthode. C'est une opération relativement lente, car il faut chercher dans l'une des collections impliquées.

14

Ils servent des objectifs différents. clear() efface une instance de la classe, removeAll() supprime tous les objets donnés et renvoie l'état de l'opération.

7
lucapette

Sauf s'il existe une optimisation spécifique qui vérifie si l'argument passé à removeAll() est la collection elle-même (et I fortement je doute qu'une telle optimisation existe) il sera significativement plus lent qu'un simple .clear().

En dehors de cela (et au moins également important): arraylist.removeAll(arraylist) n'est qu'un code obtus et déroutant. C'est une façon très arriérée de dire "efface cette collection". Quel avantage aurait-il sur très compréhensiblearraylist.clear()?

7
Joachim Sauer

clear() passera par le tableau sous-jacent et définira chaque entrée sur null;

removeAll(collection) va parcourir la liste de tableaux pour rechercher une collection et remove(Object) s'il existe.

J'imagine que clear() est bien plus rapide que removeAll car ce n'est pas une comparaison, etc.

4
Nicholas

Clear est plus rapide car il ne parcourt pas les éléments à supprimer. Cette méthode peut supposer que TOUS les éléments peuvent être supprimés.

Remove all ne signifie pas nécessairement supprimer tous les éléments de la liste, seuls ceux fournis en tant que paramètres DEVRAIENT être supprimés. Par conséquent, des efforts supplémentaires sont nécessaires pour conserver ceux qui ne devraient pas être supprimés.

CLARIFICATION

Par "boucle", je veux dire qu'il n'est pas nécessaire de vérifier si l'élément doit être conservé ou non. Il peut définir la référence sur null sans rechercher dans les listes d'éléments à supprimer fournies.

Clear IS plus rapide que deleteall.

2
Jérôme Verstrynge

clear () sera beaucoup plus efficace. Il va simplement supprimer chaque élément. L'utilisation de removeAll (arraylist) demandera beaucoup plus de travail, car elle vérifiera chaque élément de l'arraylist pour voir s'il existe déjà avant de le supprimer.

1
CDelaney