removeAll()时TreeSet中的NullPointerException
从Collection.removeAll()
的文档:
抛出:
NullPointerException
– 如果此collection包含一个或多个null元素且指定的collection不支持null元素(可选),或者指定的collection为null。
但是下面的代码仍然会抛出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); } }
有人能帮我理解这种行为吗?
我猜Javadoc的条件是什么时候可能会被removeAll
抛出NullPointerException
是不准确的。
TreeSet
的removeAll
依赖于AbstractSet
的实现。 该实现迭代了两组中较小的所有元素。
在你的代码片段中,这是包含null
元素的HashSet
。 因此removeAll
遍历HashSet
并尝试从TreeSet
删除它找到的每个元素。
但是,当尝试从uses natural ordering, or its comparator does not permit null elements
集合中删除null
元素uses natural ordering, or its comparator does not permit null elements
时, remove
TreeSet
会抛出NullPointerException
。
总而言之, NullPointerException
是由TreeSet
的remove()
引起的,这在remove()
的Javadoc中有解释:
抛出:
ClassCastException – 如果指定的对象无法与此set中当前的元素进行比较
NullPointerException – 如果指定的元素为null并且此set使用自然排序 ,或者其比较器不允许null元素
有趣的是,向HashSet
添加一个元素将消除NullPointerException
,因为在这种情况下,两个Set
将具有相同的大小,并且removeAll()
的实现将迭代TreeSet
的元素。
好的,从TreeSet的remove方法抛出Nullpointerexception
。 下面是Treeset的removeAll()
方法的源代码
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 }
removeAll()
方法在内部调用remove()
。由于你使用一些null
值执行, TreeSet的remove()方法无法处理它,因此也无法处理exception。
NullPointerException – 如果指定的元素为null并且此set使用自然排序,或者其比较器不允许null元素