Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4759223

(coll) ArrayList constructor should assign result of Collection.toArray(Object[])

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Duplicate
    • Affects Version/s: 1.4.1
    • Fix Version/s: None
    • Component/s: core-libs
    • Labels:

      Description

      Name: gm110360 Date: 10/07/2002


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

      Also:

      java version "1.3.1_03"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_03-b03)
      Java HotSpot(TM) Client VM (build 1.3.1_03-b03, mixed mode)

      FULL OPERATING SYSTEM VERSION :

      Linux 2.4.19-gentoo-r9 running on an AMD XP.

      ADDITIONAL OPERATING SYSTEMS :

      This is an issue with the code in the standard Java
      libraries. I have not checked, but it should be operating
      system independent.

      A DESCRIPTION OF THE PROBLEM :
      ArrayList constructor should assign result of
      Collection.toArray(Object[])

      I would like to suggest a change to one of ArrayList's
      constructors. This improvement would solve a problem for me,
      but it would also eliminate a minor race condition.

      The change is simple enough that it might be worth making,
      despite its limited benefit.


      At the moment one of the constructors for ArrayList looks
      like this:

          public ArrayList(Collection c) {
              size = c.size();
              // Allow 10% room for growth
              elementData = new Object[
                           
      (int)Math.min((size*110L)/100,Integer.MAX_VALUE)];
              c.toArray(elementData);
          }

      I think that the last line should be changed to:

              elementData = c.toArray(elementData);


      Usually, the behaviour of the two pieces of code would be
      just the same. However the change would allow it to cope
      with two situations. As I mentioned earlier, one is a minor
      race condition. The other is more difficult to deal with, is
      only likely to affect me.

      [Situation 1] The size of the collection changes.

      If the Collection's size changes (by over 10%) between the
      call to c.size() and the call to c.toArray() then the
      changed code will work correctly. The original code will
      populate the ArrayList with a truncated version of the
      Collection.

      This fixes a small problem, but I think it is worth making.
      This race condition might not look particularly important,
      but an ArrayList is often used (by me, anyway) to take a
      'snapshot' of a synchronized List. It would be nice if the
      operation was atomic.

      [Situation 2] When the Collection is a 'remote' object.

      In my application I am wrapping Java's collections so they
      can work natively in the Ozone ODB
      (http://www.ozone-db.org/). In this application, the
      toArray(Object[]) method is sometimes called on a proxy
      Collection object.

      The proxy Collection operates just like a normal Collection
      except it de/serializes the arguments and return values.
      This means that using the array as an in/out variable
      doesn't work. If I try to construct an ArrayList from a
      proxy Collection I just get a List of nulls.


      In conclusion, this change would make the code more robust
      under unusual conditions. It would impose a small
      performance cost (an extra assignment), but I think this is
      justified. The real cost is the cost of retesting, which I
      can't really comment on.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      CUSTOMER WORKAROUND :
      I am describing a flaw in the code rather than its
      behaviour, so there is no real workaround. However, there is
      a workaround for the examples I use in each the situations I
      describe.

      [Situation 1] Getting an atomic copy of a synchronized list

      Arrays.asList(synchronizedList.toArray())

      [Situation 2] Getting a copy of a 'remote' list

      Arrays.asList(remoteList.toArray())
      (Review ID: 165338)
      ======================================================================

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              martin Martin Buchholz
              Reporter:
              gmanwanisunw Girish Manwani (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: