Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between an empty ArrayList and an ArrayList with null elements?

I am coding some validators for a REST service which parse a JSON and I found out something that sounds wierd for me (I am not a JAVA expert at all).

Consider having two ArrayLists:

ArrayList<Object> list1 = new ArrayList<Object>();
ArrayList<Object> list2 = new ArrayList<Object>();

Both lists have something in common: they are completely empty (or full of null elements). But if I do:

list1.add(null);

Although both remain completely empty, they have completely different behaviors. And to make some methods the results are very different:

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

Doing some research, and looking at the implementation of each of these methods, you can determine the reason for these differences, but still do not understand why it would be valid or useful to differentiate between these lists.

  • Why add(item) doesnt validate if item!=null ?
  • Why contains(null) says false if the list is full of nulls?

Thanks in advance!!!

EDIT:

I am mostly agree whit the answers, but I'm not yet convinced all. This is the implementation of the method remove:

/**
 * 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
 * <tt>i</tt> such that
 * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
 * (if such an element exists).  Returns <tt>true</tt> 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 <tt>true</tt> 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
}

So, now if i do:

ArrayList<Object> list = new ArrayList<Object>();
list.add(null);
System.out.println(list.contains(null)); //prints true!
list.remove(null);
System.out.println(list.contains(null));  //prints false!

what I'm missing?

like image 465
melli-182 Avatar asked Nov 24 '15 19:11

melli-182


People also ask

Is an empty ArrayList the same as null?

No. An ArrayList can be empty (or with nulls as items) an not be null. It would be considered empty.

What is the difference between null and empty list?

An empty collection is actually a collection, but there aren't any elements in it yet. null means no collection exists at all.

Can ArrayList contain null elements?

In ArrayList, any number of null elements can be stored. While in HashMap, only one null key is allowed, but the values can be of any number.

How do you check if an ArrayList contains null value?

v == null : o. equals(v) ). i.e. if o is null , it returns true only if one element is null in the ArrayList. If o is not null , it returns true only if at least one element equal to v.


2 Answers

A list containing null is NOT empty. It contains null. Lists are allowed to contain null, so you can put null in it if you want.

like image 93
dsh Avatar answered Sep 23 '22 10:09

dsh


An ArrayList explicitly is allowed and able to store null values, because they might be meaningful to your program. And empty list is empty (i.e. doesn't contain anything, not even null. After you successfully add(null) (it returns true to signal success), the list must obviously return true on contains(null) as well. In fact, you can even remove(null) from that list and it will be empty again.

like image 38
Wormbo Avatar answered Sep 21 '22 10:09

Wormbo