我想知道为什么HashSet,LinkedHashSet和TreeSet实现不允许null元素? 每当我尝试运行以下代码时,它都会抛出一个空指针异常。
public static void main(String[] args) {
HashSet<Integer> hashSet = new HashSet<Integer>();
hashSet.add(2);
hashSet.add(5);
hashSet.add(1);
// hashSet.add(null); will throw null pointer
hashSet.add(999);
hashSet.add(10);
hashSet.add(10);
hashSet.add(11);
hashSet.add(9);
hashSet.add(10);
hashSet.add(000);
hashSet.add(999);
hashSet.add(0);
Iterator<Integer> it = hashSet.iterator();
while(it.hasNext()){
int i = it.next();
System.out.print(i+" ");
}
}
请指导我。
答案 0 :(得分:54)
这就是为什么我不喜欢依靠自动拳击。 Java Collections无法存储原语(为此您需要第三方API,如Trove)。所以,实际上,当你执行这样的代码时:
hashSet.add(2);
hashSet.add(5);
真正发生的事情是:
hashSet.add(new Integer(2));
hashSet.add(new Integer(5));
在哈希集中添加null是 不 问题,该部分工作得很好。当您尝试将值拆分为原始int时,您的NPE会出现:
while(it.hasNext()){
int i = it.next();
System.out.print(i+" ");
}
当遇到null
值时,JVM会尝试将其拆分为int原语,从而导致NPE。您应该更改代码以避免这种情况:
while(it.hasNext()){
final Integer i = it.next();
System.out.print(i+" ");
}
答案 1 :(得分:21)
1)你确定你得到编译时间错误吗?我不这么认为,我想代码在运行时抛出NPE
int i = it.next();
2)事实上java.util.Set接口不禁止null元素,并且一些JCF Set实现也允许null元素:
设置API - A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element.
HashSet API - This class permits the null element
。
LinkedHashSet API - This class provides all of the optional Set operations, and permits null elements
TreeSet.add API - throws NullPointerException - if the specified element is null and this set uses natural ordering, or its comparator does not permit null elements
答案 2 :(得分:6)
不,设置接口允许空值仅限其实现,即TreeSet
不允许空值。
即使您没有编写迭代代码并且代码中只有oTreeSet.add(null)
,它也会在运行时抛出NullPointerException。
TreeSet
类的add()
方法在内部调用TreeMap类的put()
方法。
{(1}}值不允许使用put()方法
null
答案 3 :(得分:4)
Set
接口的要点是使用有关元素(哈希码或比较)的信息来加快实现。
null
没有这些信息。
答案 4 :(得分:4)
Set Interface不允许为null,因为在TreeSet中,它以排序顺序存储元素,所以每次添加新元素时它会比较值然后进行排序。所以内部发生的事情是它将新添加的空值与现有值进行比较,因此它将抛出NullPointerException。
String str=null;
if(str.equals("abc"))
{
}
//it will throw null pointer exception
这就是为什么它不允许空值。
答案 5 :(得分:1)
您提到过:
<块引用>// hashSet.add(null);会抛出空指针
这是不正确的,因为 HashSet
确实允许向其中添加 null
,因此,您不会遇到此语句的任何编译失败或运行时异常。但是,当下面的语句将被执行时
int i = it.next();
您将收到如下所示的运行时异常:
<块引用>线程“main”中的异常java.lang.NullPointerException:不能 调用“java.lang.Integer.intValue()”因为返回值 "java.util.Iterator.next()" 在 Main.main(Main.java:24) 处为空
例外是不言自明的。 JLS §5.1.8 指定如下:
<块引用>如果 r 为 null,拆箱转换会抛出 NullPointerException
下面给出了另一个理解这个概念的例子:
public class Main {
public static void main(String[] args) {
Integer x = null;
print(x);
}
static void print(int x) {
System.out.println(x);
}
}
输出:
<块引用>线程“main”中的异常java.lang.NullPointerException:不能 调用“java.lang.Integer.intValue()”因为“x”在 Main.main(Main.java:7)
事实上,编译器会提前警告你:
<块引用>空指针访问:这个Integer类型的表达式为空但是 需要自动拆箱
答案 6 :(得分:0)
public class JavaHashSetTest {
public static void main(String[] args) {
Set<Integer> hashset= new HashSet<Integer>();
hashset.add(null);
hashset.add(22);
hashset.add(222);
hashset.add(null);
hashset.add(11);
hashset.add(233);
// TreeSet<String> tset=hashset;
Iterator<Integer> it = hashset.iterator();
while(it.hasNext()){
Integer i = it.next();
System.out.print(i+" ");
}
}
}
我的代码正在运行,为什么它会给你Nullpointer 我试图对包含Null值的hashset进行排序,然后它会给你异常,否则它工作正常。
答案 7 :(得分:0)
只有TreeSet
将获得运行时间Null pointer Exception
,而HashSet
在编译时将不会出现任何错误,并且在运行时它将仅允许一个null
值,如果输入除此之外,它还会超过HashSet
。看到这里:
public class HasSetDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
//no error it will print only one null and 2,5,8
Set<Integer> s = new HashSet<Integer>();
s.add(2);
s.add(5);
s.add(8);
s.add(null);
s.add(null);//it will override and hashset will allow one null value
Iterator i=s.iterator();
while(i.hasNext()){
Object in=(Object)i.next();
System.out.println(" hi "+in);
}
}
}
hi null
hi 2
hi 5
hi 8
public class SetDemo {
public static void main(String[] args) {
// either its may be string or integer it will give NullPointerException in run time
Set<String> s2 = new TreeSet<>();
s2.add("ramana");
s2.add(null);
s2.add("4");
s2.add("5");
s2.add(null);
Iterator<String> i=s2.iterator();
while(i.hasNext()){
System.out.println(i.next());
}
}
}
Exception in thread "main" java.lang.NullPointerException
at java.util.TreeMap.put(Unknown Source)
at java.util.TreeSet.add(Unknown Source)
at com.sagili.set.SetDemo.main(SetDemo.java:13)
答案 8 :(得分:-1)
将空值添加到集合(如HashSet Arraylist)只有在使用集合进行排序时才会产生问题。除此之外,null将适用于迭代器和正常场景,以显示列表或集的内容。
答案 9 :(得分:-1)
Set interface在内部使用HashMap实现类。当我们使用add()时,我们提供的值作为值的关键存储在Map中,它会创建一个空对象。
因此,地图不允许重复。