To implement an unmodifiable collection, the programmer needs only to extend this class and provide implementations for the iterator and size methods. (The iterator returned by the iterator method must implement hasNext and next.)
To implement a modifiable collection, the programmer must additionally override this class’s add method (which otherwise throws an UnsupportedOperationException), and the iterator returned by the iterator method must additionally implement its remove method.
//.... public <T> T[] toArray(T[] a) { // Estimate size of array; be prepared to see more or fewer elements intsize= size(); // a[] has less size than size() reflection --> new Instance T[] r = a.length >= size ? a : (T[])java.lang.reflect.Array .newInstance(a.getClass().getComponentType(), size);
Iterator<E> it = iterator(); for (inti=0; i < r.length; i++) { if (! it.hasNext()) { // fewer elements than expected if (a == r) {//预留空间充足 r[i] = null; // null-terminate } elseif (a.length < i) {//预留空间不足:不足以容纳实际元素 return Arrays.copyOf(r, i); } else {//预留空间不足:足以容纳实际元素 System.arraycopy(r, 0, a, 0, i); if (a.length > i) { a[i] = null; } } return a; } r[i] = (T)it.next(); } // more elements than expected return it.hasNext() ? finishToArray(r, it) : r; }
// more elements than expected, just stored the first i elements. privatestatic <T> T[] finishToArray(T[] r, Iterator<?> it) { inti= r.length; while (it.hasNext()) { intcap= r.length; if (i == cap) {//内存扩容 intnewCap= cap + (cap >> 1) + 1; // overflow-conscious code if (newCap - MAX_ARRAY_SIZE > 0) newCap = hugeCapacity(cap + 1); r = Arrays.copyOf(r, newCap); } r[i++] = (T)it.next(); } // trim if overallocated return (i == r.length) ? r : Arrays.copyOf(r, i); }
To implement an unmodifiable list, the programmer needs only to extend this class and provide implementations for theget(int) and size() methods.
To implement a modifiable list, the programmer must additionally override the set(int, E) method (which otherwise throws an UnsupportedOperationException). If the list is variable-size the programmer must additionally override the add(int, E) andremove(int)methods.
need to implement get(), size() ,,, set(), add()
In this class, it has implemented Iterable#iterator(), List#listIterator
privateclassItrimplementsIterator<E> { //Index of element to be returned by subsequent call to next. intcursor=0;
/** * Index of element returned by most recent call to next or previous. * Reset to -1 if this element is deleted by a call to remove. */ intlastRet= -1;
/** * The modCount value that the iterator believes that the backing List should have. * If this expectation is violated, the iterator has detected concurrent modification. */ intexpectedModCount= modCount;
public E next() { checkForComodification(); try { inti= cursor; Enext= get(i); lastRet = i; cursor = i + 1; return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); thrownewNoSuchElementException(); } }
publicvoidremove() { if (lastRet < 0) thrownewIllegalStateException(); checkForComodification(); try { AbstractList.this.remove(lastRet); if (lastRet < cursor) cursor--;//回退 lastRet = -1;//Reset to -1 if this element is deleted by a call to remove. expectedModCount = modCount; } catch (IndexOutOfBoundsException e) { thrownewConcurrentModificationException(); } }
finalvoidcheckForComodification() { if (modCount != expectedModCount) thrownewConcurrentModificationException(); } }
An iterator over a collection. {@code Iterator} takes the place of {@link Enumeration} in the Java Collections Framework. Iterators differ from enumerations in two ways:
Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics.
Method names have been improved.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
publicinterfaceIterator<E> { booleanhasNext(); E next();
An object that implements the Enumeration interface generates a series of elements, one at a time. Successive calls to the nextElement method return successive elements of the series. For example, to print all elements of a Vector<E>v:
1 2
for (Enumeration<E> e = v.elements(); e.hasMoreElements();) System.out.println(e.nextElement());
Methods are provided to enumerate through the elements of a vector, the keys of a hashtable, and the values in a hashtable. Enumerations are also used to specify the input streams to a SequenceInputStream.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
publicinterfaceEnumeration<E> { /** * Tests if this enumeration contains more elements. * * @return <code>true</code> if and only if this enumeration object * contains at least one more element to provide; * <code>false</code> otherwise. */ booleanhasMoreElements();
/** * Returns the next element of this enumeration if this enumeration * object has at least one more element to provide. * * @return the next element of this enumeration. * @exception NoSuchElementException if no more elements exist. */ E nextElement(); }
FieldmodCountField= AbstractList.class.getDeclaredField("modCount"); modCountField.setAccessible(true); //can't get the private class : ArrayList.Itr //Field expectedModCountField=ArrayList.Itr.class.getDeclaredField("Itr"); longoffset= unsafe.objectFieldOffset(modCountField); for (Object o : list) { list.remove(o);//Exception //缺少回退当前指针 unsafe.putInt(list, offset, (int) modCountField.get(list) - 1);//but can not back ... and the modCount is wrong ! modCount: the modified times } System.out.println("list: " + list.toArray() + "\t" + Arrays.toString(list.toArray()) + "\t" + list.size());