web-dev-qa-db-ja.com

これらのセットはnullを許可します。 null要素を追加できないのはなぜですか?

HashSet、LinkedHashSet、TreeSetの実装がnull要素を許可しない理由を知りたいのですが?次のコードを実行しようとすると、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+" ");
    }
    }

案内してください。

25
nakul

これが、オートボクシングに依存したくない理由です。 Javaコレクションはプリミティブを保存できません(そのため、 Trove のようなサードパーティAPIが必要になります)。したがって、実際に次のようなコードを実行する場合:

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

実際に起こっていることは:

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

ハッシュセットにnullを追加することはnotです。その部分は正常に機能します。 NPEは、値をプリミティブなintにアンボックスしようとすると、後で表示されます。

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

1)コンパイル時間エラーが発生してもよろしいですか?私はそうは思わない、私はコードが実行時にNPEをスローすると思います

int i = it.next();

2)実際のところ、Java.util.Setインターフェースはヌル要素を禁止しておらず、一部のJCFセット実装ではヌル要素も許可しています。

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

21

いいえ、Set Interface do null value allowその実装のみ、つまりTreeSetはnull値を許可しません。

繰り返しコードを記述しておらず、コード内にoTreeSet.add(null)のみがコンパイルされ、実行時にNullPointerExceptionがスローされます

TreeSetクラスのadd()メソッドは、TreeMapクラスのput()メソッドを内部的に呼び出します。 null値は、put()メソッドの以下のコードとして許可されていません

if (key == null)
     throw new NullPointerException();
6
Shrikant Dande

Set Interfaceはnullを許可しません。これは、TreeSetでは要素をソート順に格納するため、新しい要素を追加するたびに値を比較してからソートするためです。内部的には、新しく追加されたnull値と既存の値を比較して、NullPointerExceptionをスローします。

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

これが、null値を許可しない理由です。

4
Sajid Patel

Setインターフェースのポイントは、要素(ハッシュコードまたは比較)に関する情報を使用して実装を高速化することです。

nullにはその情報がありません。

4
SLaks

Setを使用すると、nullを追加できるため、問題にはなりません。第二に、Javaプログラムを最初にコンパイルしてバイトコードに変換してから実行する必要があります。NullPointerExceptionは実行中にスローされる例外です。問題:NPEが発生した理由を分析してみましょう。

ここでIteratorInteger型のオブジェクトを出力することになっているので、結果を_primitive type int_変数に保存します。整数は、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()が呼び出され、整数のオブジェクトをプリミティブintに変換します。 it.next()がnullを返す場合、null.intValue()が実行され、NullPointerExceptionになります。

intの代わりにIntegerが使用されている場合、例外はありません

_Integer i = it.next();
_
1
nits.kk

TreeSetのみが実行時間を取得しますNull pointer ExceptionおよびHashSetはコンパイル時にエラーを取得せず、実行時に1つの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

ケース2:

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)
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値を含むハッシュセットをソートしようとすると、例外が発生します。

0
user4948462