Разница между пустым ArrayList и ArrayList с нулевыми элементами?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Разница между пустым ArrayList и ArrayList с нулевыми элементами?

Сообщение Anonymous »

Я пишу несколько валидаторов для службы REST, которая анализирует JSON, и обнаружил кое-что, что звучит странно для меня (я вообще не эксперт по Java).
Рассмотрите возможность использования два списка ArrayList:

Код: Выделить всё

ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList();
Оба списка имеют что-то общее: они совершенно пусты (или полны нулевых элементов). Но если я это сделаю:

Код: Выделить всё

list1.add(null);
Хотя оба остаются совершенно пустыми, они ведут себя совершенно по-разному. А при использовании некоторых методов результаты очень разные:

Код: Выделить всё

System.out.println(list1.contains(null));  //prints true!
System.out.println(list2.contains(null));  //prints false

System.out.println(CollectionUtils.isNotEmpty(list1));  //prints true
System.out.println(CollectionUtils.isNotEmpty(list2));  //prints false

System.out.println(list1.size());  //prints 1
System.out.println(list2.size());  //prints 0
Проведя некоторое исследование и посмотрев на реализацию каждого из этих методов, вы можете определить причину этих различий, но до сих пор не понимаете, почему было бы правильно или полезно проводить различие между эти списки.
  • Почему add(item) не проверяет, если item!=null?
  • Почему contains(null) говорит false, если список полон нулей?
Я в основном согласен с ответами , но я еще не во всем убедился. Это реализация метода удаления:

Код: Выделить всё

/**
* Removes the first occurrence of the specified element from this list,
* if it is present.  If the list does not contain the element, it is
* unchanged.  More formally, removes the element with the lowest index
* i such that
* (o==null ? get(i)==null : o.equals(get(i)))
* (if such an element exists).  Returns true if this list
* contained the specified element (or equivalently, if this list
* changed as a result of the call).
*
* @param o element to be removed from this list, if present
* @return true if this list contained the specified element
*/
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}

/*
* Private remove method that skips bounds checking and does not
* return the value removed.
*/
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}
Итак, если я это сделаю:

Код: Выделить всё

ArrayList list = new ArrayList();
list.add(null);
System.out.println(list.contains(null)); //prints true!
list.remove(null);
System.out.println(list.contains(null));  //prints false!
Чего мне не хватает?

Подробнее здесь: https://stackoverflow.com/questions/339 ... l-elements
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»