有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java这些集合允许null。为什么我不能添加空元素?

我想知道为什么HashSet、LinkedHashSet和TreeSet实现不允许空元素? 每当我尝试运行以下代码时,它都会抛出一个空指针异常

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

请引导我


共 (6) 个答案

  1. # 1 楼答案

    Set接口不允许null,因为在TreeSet中,它按排序顺序存储元素,所以每次我们添加新元素时,它都会比较值,然后进行排序。所以在内部,它将新添加的null值与现有值进行比较,从而抛出NullPointerException

    String str=null;
    if(str.equals("abc"))
    {
    }
    //it will throw null pointer exception
    

    这就是为什么它不允许空值

  2. # 2 楼答案

    不,设置接口不允许空值只有它的实现,即TreeSet不允许空值

    即使您没有编写迭代代码,并且代码中只有oTreeSet.add(null),它也会编译,并在运行时抛出NullPointerException

    TreeSet类的add()方法在内部调用TreeMap类的put()方法。 ^在put()方法中不允许使用{}值,如下代码所示

    if (key == null)
         throw new NullPointerException();
    
  3. # 3 楼答案

    1)你确定你会在编译时出错吗?我不这么认为,我猜代码在运行时在

    int i = it.next();

    2)事实上是java。util。Set接口不禁止空元素,一些JCF Set实现也允许空元素:

    设置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。添加API-throws NullPointerException - if the specified element is null and this set uses natural ordering, or its comparator does not permit null elements

  4. # 4 楼答案

    这就是为什么我不喜欢依赖自动拳击。Java集合不能存储原语(为此,您需要像Trove这样的第三方API)。所以,当你执行这样的代码时:

    hashSet.add(2);
    hashSet.add(5);
    

    真正发生的是:

    hashSet.add(new Integer(2));
    hashSet.add(new Integer(5));
    

    将空值添加到哈希集是而不是问题在于,这部分工作正常。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+" ");
    }
    
  5. # 5 楼答案

    Set允许添加null,所以这不是问题。其次,需要先编译Java程序,将其转换为字节码,然后执行NullPointerException是在运行时引发的异常。编译时这应该不是问题。现在让我们分析一下为什么你会得到NPE

    Iterator这里应该输出类型为Integer的对象,我们希望将结果存储在primitive type int变量中。Integer是一个类,它可以将其类型的引用引用为null,但原语不能包含null值

    Iterator<Integer> it = hashSet.iterator(); // Iterator of Type Integer
    while(it.hasNext()){
        int i = it.next(); // it.next outputs Integer, but result is tried to be held in a primitive type variable
        System.out.print(i+" ");
    }
    

    当执行int i = it.next();时,调用public int intValue()将Integer对象转换为基元int。当it.next()返回null时,执行null.intValue(),结果是NullPointerException

    如果使用Integer而不是int,那么就不会有例外

    Integer i = it.next();
    
  6. # 6 楼答案

    Set接口的要点是使用有关元素的信息(哈希代码或比较)来加快实现速度

    null没有这些信息