3 votes

NullPointerException dans TreeSet lors de removeAll()

D'après les documents de Collection.removeAll() :

Les lancers : NullPointerException - si cette collection contient un ou plusieurs éléments null et que la collection spécifiée ne prend pas en charge éléments nuls (facultatif), ou si la collection spécifiée est nulle.

Mais le code ci-dessous génère toujours un NullPointerException :

public class TestSet { 
    public static void main(String[] args) { 
        Set set1 = new TreeSet(); 
        set1.add("A"); 
        set1.add("B"); 
        Set set2 = new HashSet(); 
        set2.add(null); 
        set1.removeAll(set2); 
    } 
} 

Quelqu'un peut-il m'aider à comprendre ce comportement ?

4voto

Eran Points 35360

Je suppose que les conditions de la Javadoc pour savoir quand NullPointerException peuvent être lancés par removeAll sont inexactes.

TreeSet 's removeAll s'appuie sur AbstractSet La mise en œuvre de la directive. Cette implémentation itère sur tous les éléments du plus petit des deux ensembles.

Dans votre extrait, il s'agit de la fonction HashSet qui contient le null élément. Ainsi, removeAll itère sur les HashSet et tente de retirer chaque élément qu'il trouve du TreeSet .

Cependant, remove de TreeSet lance un NullPointerException lorsqu'on essaie de supprimer un null élément de l'ensemble qui uses natural ordering, or its comparator does not permit null elements .

Pour résumer, le NullPointerException est causée par TreeSet 's remove() qui est expliqué dans la Javadoc de l'application remove() :

Les lancers :

ClassCastException - si l'objet spécifié ne peut pas être comparé aux éléments actuellement dans cet ensemble

NullPointerException - si l'élément spécifié est nul et que cet ensemble utilise un ordre naturel. ou son comparateur n'autorise pas les éléments nuls.

Il est intéressant de noter que l'ajout d'un élément supplémentaire à l'indice HashSet éliminerait le NullPointerException puisque dans ce cas, les deux Set auraient la même taille, et la mise en œuvre de l'option removeAll() itèrerait sur les éléments du TreeSet .

2voto

Ok, le Nullpointerexception Lancé par la méthode remove de TreeSet. Ci-dessous, le code source de la méthode Treeset removeAll() méthode

public boolean removeAll(Collection<?> c) {
167        boolean modified = false;
168
169        if (size() > c.size()) {
170            for (Iterator<?> i = c.iterator(); i.hasNext(); )
171                modified |= remove(i.next());
172        }

Le site removeAll() en appelant en interne la méthode remove() Puisque vous vous produisez avec des null valeurs , La fonction remove() de TreeSet ne peut pas le traiter, d'où l'exception.

NullPointerException - si l'élément spécifié est nul et que cet ensemble utilise un ordre naturel ou que son comparateur ne permet pas les éléments nuls.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X