ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/AbstractCollection.java
(Generate patch)

Comparing jsr166/src/main/java/util/AbstractCollection.java (file contents):
Revision 1.8 by jsr166, Sun May 28 23:36:29 2006 UTC vs.
Revision 1.9 by jsr166, Sun Jun 25 19:07:16 2006 UTC

# Line 26 | Line 26 | package java.util;
26   * <tt>Collection</tt> constructor, as per the recommendation in the
27   * <tt>Collection</tt> interface specification.<p>
28   *
29 < * The documentation for each non-abstract methods in this class describes its
29 > * The documentation for each non-abstract method in this class describes its
30   * implementation in detail.  Each of these methods may be overridden if
31   * the collection being implemented admits a more efficient implementation.<p>
32   *
# Line 95 | Line 95 | public abstract class AbstractCollection
95      /**
96       * {@inheritDoc}
97       *
98 <     * <p>This implementation allocates the array to be returned, and iterates
99 <     * over the elements in the collection, storing each object reference in
100 <     * the next consecutive element of the array, starting with element 0.
98 >     * <p>This implementation returns an array containing all the elements
99 >     * returned by this collection's iterator, in the same order, stored in
100 >     * consecutive elements of the array, starting with index {@code 0}.
101 >     * The length of the returned array is equal to the number of elements
102 >     * returned by the iterator, even if the size of this collection changes
103 >     * during iteration, as might happen if the collection permits
104 >     * concurrent modification during iteration.  The {@code size} method is
105 >     * called only as an optimization hint; the correct result is returned
106 >     * even if the iterator returns a different number of elements.
107 >     *
108 >     * <p>This method is equivalent to:
109 >     *
110 >     *  <pre> {@code
111 >     * List<E> list = new ArrayList<E>(size());
112 >     * for (E e : this)
113 >     *     list.add(e);
114 >     * return list.toArray();
115 >     * }</pre>
116       */
117      public Object[] toArray() {
118          // Estimate size of array; be prepared to see more or fewer elements
119          Object[] r = new Object[size()];
105        int i = 0;
120          Iterator<E> it = iterator();
121 <        while (i < r.length && it.hasNext())
122 <            r[i++] = it.next();
123 <        // Trim if overallocated; expand if underallocated
124 <        if (i < r.length || it.hasNext())
125 <            return resizeAndFinishToArray(r, i, it);
126 <        return r;
121 >        for (int i = 0; i < r.length; i++) {
122 >            if (! it.hasNext()) // fewer elements than expected
123 >                return Arrays.copyOf(r, i);
124 >            r[i] = it.next();
125 >        }
126 >        return it.hasNext() ? finishToArray(r, it) : r;
127      }
128  
129      /**
130       * {@inheritDoc}
131       *
132 <     * <p>This implementation checks if the array is large enough to contain the
133 <     * collection; if not, it allocates a new array of the correct size and
134 <     * type (using reflection).  Then, it iterates over the collection,
135 <     * storing each object reference in the next consecutive element of the
136 <     * array, starting with element 0.  If the array is larger than the
137 <     * collection, a <tt>null</tt> is stored in the first location after the
138 <     * end of the collection.
132 >     * <p>This implementation returns an array containing all the elements
133 >     * returned by this collection's iterator in the same order, stored in
134 >     * consecutive elements of the array, starting with index {@code 0}.
135 >     * If the number of elements returned by the iterator is too large to
136 >     * fit into the specified array, then the elements are returned in a
137 >     * newly allocated array with length equal to the number of elements
138 >     * returned by the iterator, even if the size of this collection
139 >     * changes during iteration, as might happen if the collection permits
140 >     * concurrent modification during iteration.  The {@code size} method is
141 >     * called only as an optimization hint; the correct result is returned
142 >     * even if the iterator returns a different number of elements.
143 >     *
144 >     * <p>This method is equivalent to:
145 >     *
146 >     *  <pre> {@code
147 >     * List<E> list = new ArrayList<E>(size());
148 >     * for (E e : this)
149 >     *     list.add(e);
150 >     * return list.toArray(a);
151 >     * }</pre>
152       *
153       * @throws ArrayStoreException  {@inheritDoc}
154       * @throws NullPointerException {@inheritDoc}
# Line 132 | Line 159 | public abstract class AbstractCollection
159          T[] r = a.length >= size ? a :
160                    (T[])java.lang.reflect.Array
161                    .newInstance(a.getClass().getComponentType(), size);
135        int i = 0;
162          Iterator<E> it = iterator();
163 <        while (i < r.length && it.hasNext())
164 <            r[i++] = (T)it.next();
165 <        // Trim if overallocated; expand if underallocated
166 <        if (it.hasNext() || (r != a && i < r.length))
167 <            return resizeAndFinishToArray(r, i, it);
168 <        if (i < r.length)
169 <            r[i] = null; // null-terminate if provided array is too big
170 <        return r;
163 >
164 >        for (int i = 0; i < r.length; i++) {
165 >            if (! it.hasNext()) { // fewer elements than expected
166 >                if (a != r)
167 >                    return Arrays.copyOf(r, i);
168 >                r[i] = null; // null-terminate
169 >                return r;
170 >            }
171 >            r[i] = (T)it.next();
172 >        }
173 >        return it.hasNext() ? finishToArray(r, it) : r;
174      }
175  
176      /**
177 <     * Reallocates the array being used within toArray that has a
178 <     * different number of elements than expected, and finishes
179 <     * filling it from the given iterator, if necessary.
180 <     *
181 <     * @param r the array
182 <     * @param i the next array index to fill
154 <     * @param it the in-progress iterator over the collection
177 >     * Reallocates the array being used within toArray when the iterator
178 >     * returned more elements than expected, and finishes filling it from
179 >     * the iterator.
180 >     *
181 >     * @param r the array, replete with previously stored elements
182 >     * @param it the in-progress iterator over this collection
183       * @return array containing the elements in the given array, plus any
184       *         further elements returned by the iterator, trimmed to size
185       */
186 <    private static <T> T[] resizeAndFinishToArray(T[] r, int i, Iterator<?> it) {
186 >    private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
187 >        int i = r.length;
188          while (it.hasNext()) {
189              int cap = r.length;
190 <            if (i < cap)
162 <                r[i++] = (T)it.next();
163 <            else {
190 >            if (i == cap) {
191                  int newCap = ((cap / 2) + 1) * 3;
192                  if (newCap <= cap) { // integer overflow
193                      if (cap == Integer.MAX_VALUE)
194                          throw new OutOfMemoryError
195                              ("Required array size too large");
196 <                    newCap = Integer.MAX_VALUE;
196 >                    newCap = Integer.MAX_VALUE;
197                  }
198 <                r = Arrays.copyOf(r, newCap);
199 <            }
198 >                r = Arrays.copyOf(r, newCap);
199 >            }
200 >            r[i++] = (T)it.next();
201          }
202          // trim if overallocated
203 <        return i == r.length ? r : Arrays.copyOf(r, i);
203 >        return (i == r.length) ? r : Arrays.copyOf(r, i);
204      }
205  
206      // Modification Operations

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines