Эти Наборы позволяют нуль. Почему я не могу добавить нулевые элементы?
Я хочу знать, почему реализация 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+" ");
}
}
Пожалуйста, ведите меня.
Ответы
Ответ 1
Вот почему я не люблю полагаться на авто-бокс. Коллекции Java не могут хранить примитивы (для этого вам понадобится сторонний API, например Trove). Итак, действительно, когда вы выполняете код следующим образом:
hashSet.add(2);
hashSet.add(5);
Что действительно происходит:
hashSet.add(new Integer(2));
hashSet.add(new Integer(5));
Добавление значения null в хэш-набор не, эта часть работает нормально. Ваш 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+" ");
}
Ответ 2
1) Вы уверены, что получаете время компиляции? Я так не думаю, я думаю, что код запускает NPE во время выполнения в
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.
API HashSet - This class permits the null element
.
LinkedHashSet API - This class provides all of the optional Set operations, and permits null elements
API TreeSet.add - throws NullPointerException - if the specified element is null and this set uses natural ordering, or its comparator does not permit null elements
Ответ 3
Нет, Set Interface допускает нулевое значение только в своей реализации, т.е. TreeSet
не допускает нулевое значение.
даже если вы не написали код итерации и в вашем коде есть только oTreeSet.add(null)
он компилируется, а во время выполнения выдает исключение NullPointerException.
TreeSet
add()
класса TreeSet
внутренне вызывает метод put()
класса TreeMap. null
значение не допускается, как показано ниже в коде метода put().
if (key == null)
throw new NullPointerException();
Ответ 4
Точка интерфейса Set
должна использовать информацию об элементах (хэш-кодах или сравнениях), чтобы сделать реализацию быстрее.
null
не имеет этой информации.
Ответ 5
Установить интерфейс не допускает нулевой, поскольку в TreeSet он сохраняет элемент в порядке сортировки, поэтому каждый раз, когда мы добавляем новый элемент, он сравнивает значение, а затем сортирует. так что внутренне, что происходит, это сравнение нового добавленного значения null с существующими значениями, поэтому он будет генерировать исключение NullPointerException.
String str=null;
if(str.equals("abc"))
{
}
//it will throw null pointer exception
Вот почему он не разрешает нулевые значения.
Ответ 6
Set позволяет добавлять нуль, так что это не проблема. Во-вторых, Java-программу необходимо сначала скомпилировать, чтобы преобразовать в байтовый код, а затем выполнить. NullPointerException
- это исключение, созданное во время выполнения. Время компиляции не должно быть проблемой. Теперь давайте проанализируем, почему вы получаете NPE.
Iterator
здесь предполагается вывести объект типа Integer
, и мы хотим сохранить результат в переменной primitive type int
. Integer - это класс, который может ссылаться на ссылки своего типа на нуль, но примитивы не могут содержать нулевые значения.
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()
вызывается для преобразования Object of Integer в примитивный int. Когда it.next()
возвращает значение null, выполняется null.intValue()
, что приводит к NullPointerException
.
если вместо int используется Integer, исключение не будет
Integer i = it.next();
Ответ 7
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
Я попытался отсортировать hashset, которые содержат значение Null, тогда он даст вам исключение, иначе он отлично работает.
Ответ 8
Только 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
Случай 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)
Ответ 9
Добавление null в коллекции, такие как HashSet Arraylist, создаст проблему только тогда, когда коллекция будет использоваться для сортировки. Помимо этого значения null будет работать для итератора и обычного сценария для отображения содержимого списка или набора.
Ответ 10
Устанавливать интерфейс внутренне использует класс реализации HashMap. Когда мы используем add(), наше предоставленное значение сохраняется в Map как ключ для значения, он создает пустой объект.
Таким образом, карта не допускает дубликатов.