title: Difference between an empty ArrayList and an ArrayList with null elements?
body: <p>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 <strong><em>JAVA expert</em></strong> at all).</p>
  
  <p>Consider having two <strong><em>ArrayLists</em></strong>: </p>
  
  <pre><code>ArrayList&lt;Object&gt; list1 = new ArrayList&lt;Object&gt;();
  ArrayList&lt;Object&gt; list2 = new ArrayList&lt;Object&gt;();
  </code></pre>
  
  <p>Both lists have something in <strong><em>common</em></strong>: they are <em>completely empty</em> (or full of null elements). But if I do:</p>
  
  <pre><code>list1.add(null);
  </code></pre>
  
  <p>Although both remain completely <strong><em>empty</em></strong>, <em>they have completely different behaviors</em>. And to make some methods the results are <strong><em>very different</em></strong>:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>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.</p>
  
  <ul>
  <li>Why <strong><em>add(item)</em></strong> doesnt validate if <strong>item!=null</strong> ?  </li>
  <li>Why <strong><em>contains(null)</em></strong> says <strong>false</strong> if the list is full of <strong>nulls</strong>?</li>
  </ul>
  
  <p>Thanks in advance!!!</p>
  
  <p><strong><em>EDIT:</em></strong></p>
  
  <p>I am mostly agree whit the answers, but I'm not yet convinced all. This is the implementation of the method remove:</p>
  
  <pre><code>/**
   * 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
   * &lt;tt&gt;i&lt;/tt&gt; such that
   * &lt;tt&gt;(o==null&amp;nbsp;?&amp;nbsp;get(i)==null&amp;nbsp;:&amp;nbsp;o.equals(get(i)))&lt;/tt&gt;
   * (if such an element exists).  Returns &lt;tt&gt;true&lt;/tt&gt; 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 &lt;tt&gt;true&lt;/tt&gt; if this list contained the specified element
   */
  public boolean remove(Object o) {
      if (o == null) {
          for (int index = 0; index &lt; size; index++)
              if (elementData[index] == null) {
                  fastRemove(index);
                  return true;
              }
      } else {
          for (int index = 0; index &lt; 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 &gt; 0)
          System.arraycopy(elementData, index+1, elementData, index,
                           numMoved);
      elementData[--size] = null; // clear to let GC do its work
  }
  </code></pre>
  
  <p>So, now if i do:</p>
  
  <pre><code>ArrayList&lt;Object&gt; list = new ArrayList&lt;Object&gt;();
  list.add(null);
  System.out.println(list.contains(null)); //prints true!
  list.remove(null);
  System.out.println(list.contains(null));  //prints false!
  </code></pre>
  
  <p><strong><em>what I'm missing?</em></strong></p>