JDK-4721752 : Implementations of Collection.addAll(Collection X) assume X's size won't change
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:collections
  • Affected Version: 1.4.0
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2002-07-26
  • Updated: 2021-03-03
  • Resolved: 2002-07-28
Related Reports
Duplicate :  
Description

Name: nt126004			Date: 07/26/2002


FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)


FULL OPERATING SYSTEM VERSION :

Linux charisma 2.4.18 #1 Fri May 24 14:29:54 EDT 2002 i686
unknown

A DESCRIPTION OF THE PROBLEM :
All the implementations of addAll(Collection X) assume that
X's size will remain fixed during the process of adding the
values. This is not necessarily true (e.g., for
WeakHashMap.keySet()).

See the source code example.

Note that a similiar problem was reported to be fixed in
4416923, but the fix was not nearly generic enough. I assume
that assigning the initial size of the Collection in the
addAll() method is to reduce the overhead of always calling
Iterator.hasNext(). If this is the case, perhaps the
addAll() implementations can catch NoSuchElementExceptions.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
[charisma tmp]$ java -cp . CollectionSizeBug
Exception in thread "main" java.util.NoSuchElementException
        at java.util.WeakHashMap$HashIterator.nextEntry(WeakHashMap.java:736)
        at java.util.WeakHashMap$KeyIterator.next(WeakHashMap.java:767)
        at java.util.LinkedList.addAll(LinkedList.java:267)
        at java.util.LinkedList.addAll(LinkedList.java:238)
        at java.util.LinkedList.<init>(LinkedList.java:90)
        at CollectionSizeBug.main(CollectionSizeBug.java:17)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.*;

public class CollectionSizeBug
{
    public static void main (String [] args)
    {
        while (true)
        {
            WeakHashMap map = new WeakHashMap ();
            for (int i = 0; i < 200; i++)
            {
                map.put (new Integer ((int)(Math.random () * 10000)), "Dummy");
            }

            for (int i = 0; i < 200; i++)
            {
                LinkedList test = new LinkedList (map.keySet ());
            }
        }
    }
}

---------- END SOURCE ----------

CUSTOMER WORKAROUND :
Manually add elements of a Collection instead of doing addAll().
(Review ID: 159520) 
======================================================================