List是大家在開發過程中用到的比較多的集合,其jdk源碼實現如下,以主要方法分析。
例子
List<String> list = new ArrayList<>();
// add(E e)
list.add("1");
list.add("2");
list.add("3");
System.out.println("-----------------------result-----------------------");
System.out.println(list);//[1, 2, 3]
System.out.println("-----------------------result-----------------------");
// void add(int index, E element)
list.add(1,"4");
System.out.println("-----------------------result-----------------------");
System.out.println(list);//[1, 4, 2, 3]
System.out.println("-----------------------result-----------------------");
// addAll(Collection<? extends E> c)
List<String> lt = new ArrayList<>();
lt.add("4");
lt.add("5");
list.addAll(lt);
System.out.println("-----------------------result-----------------------");
System.out.println(list);//[1, 4, 2, 3, 4, 5]
System.out.println("-----------------------result-----------------------");
// addAll(int index, Collection<? extends E> c)
list.addAll(4,lt);
System.out.println("-----------------------result-----------------------");
System.out.println(list);//[1, 4, 2, 3, 4, 5, 4, 5]
System.out.println("-----------------------result-----------------------");
// remove(int index);
list.remove(1);
System.out.println("-----------------------result-----------------------");
System.out.println(list);//[1, 2, 3, 4, 5, 4, 5]
System.out.println("-----------------------result-----------------------");
// remove(Object o);
List<User> listUsers = new ArrayList<>();
User user1 = new User("小小");
User user2 = new User("塔基哥");
listUsers.add(user1);
listUsers.add(user2);
listUsers.remove(user1);
System.out.println("-----------------------result-----------------------");
System.out.println(listUsers+">>>>>>>>"+listUsers.get(0).getName());//[com.java.test.User@4f801c4]>>>>>>>>塔基哥
System.out.println("-----------------------result-----------------------");
// T[] toArray(T[] a)
System.out.println("-----------------------result-----------------------");
String[] num_ary = list.toArray(new String[]{});
StringBuffer sf = new StringBuffer();
for(String num_str:num_ary){
if("".equals(sf.toString()))
sf.append(num_str);
else
sf.append(","+num_str);
}
System.out.println(list.toArray(num_ary)+">>>>>>>>["+sf.toString()+"]");//[Ljava.lang.String;@61bf61a0>>>>>>>>[1,2,3,4,5,4,5]
System.out.println("-----------------------result-----------------------");
// contains(Object o);
System.out.println("-----------------------result-----------------------");
System.out.println(listUsers.contains(user2));//true
System.out.println("-----------------------result-----------------------");
// containsAll(Collection<?> c);
List<User> listUsersTemp = new ArrayList<>();
listUsersTemp.add(user2);
System.out.println("-----------------------result-----------------------");
System.out.println(listUsers.containsAll(listUsersTemp));//true
System.out.println("-----------------------result-----------------------");
// subList(int fromIndex, int toIndex)
List<String> listSubList = new ArrayList<>(list.subList(1,3));
System.out.println("-----------------------result-----------------------");
System.out.println(listSubList);//[2, 3]
System.out.println("-----------------------result-----------------------");
// equals(Object o);
List<String> listEqs = new ArrayList<>();
listEqs.add("111");
List<String> listEqst = new ArrayList<>();
listEqst.add("111");
System.out.println("-----------------------result-----------------------");
System.out.println(listEqs.equals(listEqst));//true
System.out.println("-----------------------result-----------------------");
// e remove(int index);
System.out.println("-----------------------result-----------------------");
System.out.println("list.get(2)>>>>>>"+list.get(2));
String remove = list.remove(2);
System.out.println(remove);
System.out.println("-----------------------result-----------------------");
// void clear();
System.out.println("-----------------------result-----------------------");
list.clear();
System.out.println(list.size());
System.out.println("-----------------------result-----------------------");
//大坑 subList
//--------------------------------subList--------------------------------
List<String> data = new ArrayList<>();
data.add("one");
data.add("two");
data.add("three");
data.add("four");
data.add("five");
List<String> listSubListTest = data.subList(2,4);
System.out.println("-----------------------result-----------------------");
System.out.println("-----------before-----------");
System.out.println("data>>>"+data);//data>>>[one, two, three, four, five]
System.out.println("listSubListTest>>>"+listSubListTest);//listSubListTest>>>[three, four]
System.out.println("-----------after-----------");
//神奇的事情發生了
listSubListTest.add("six");
System.out.println("data>>>"+data);//data>>>[one, two, three, four, six, five]
System.out.println("listSubListTest>>>"+listSubListTest);//listSubListTest>>>[three, four, six]
System.out.println("-----------------------result-----------------------");
//--------------------------------subList--------------------------------
這是ArrayList的源碼裏聲明的幾個變量
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* Shared empty array instance used for empty instances.
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == EMPTY_ELEMENTDATA will be expanded to
* DEFAULT_CAPACITY when the first element is added.
*/
private transient Object[] elementData;
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;
1、add(E e)
List<String> list = new ArrayList<>();
// add(E e)
list.add("1");
list.add("2");
list.add("3");
System.out.println("-----------------------result-----------------------");
System.out.println(list);//[1, 2, 3]
System.out.println("-----------------------result-----------------------");
具體實現如下
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
/**
* A version of rangeCheck used by add and addAll.
*/
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
/**
* Copies the specified array, truncating or padding with nulls (if necessary)
* so the copy has the specified length. For all indices that are
* valid in both the original array and the copy, the two arrays will
* contain identical values. For any indices that are valid in the
* copy but not the original, the copy will contain <tt>null</tt>.
* Such indices will exist if and only if the specified length
* is greater than that of the original array.
* The resulting array is of exactly the same class as the original array.
*
* @param original the array to be copied
* @param newLength the length of the copy to be returned
* @return a copy of the original array, truncated or padded with nulls
* to obtain the specified length
* @throws NegativeArraySizeException if <tt>newLength</tt> is negative
* @throws NullPointerException if <tt>original</tt> is null
* @since 1.6
*/
public static <T> T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass());
}
/**
* Copies the specified array, truncating or padding with nulls (if necessary)
* so the copy has the specified length. For all indices that are
* valid in both the original array and the copy, the two arrays will
* contain identical values. For any indices that are valid in the
* copy but not the original, the copy will contain <tt>null</tt>.
* Such indices will exist if and only if the specified length
* is greater than that of the original array.
* The resulting array is of the class <tt>newType</tt>.
*
* @param original the array to be copied
* @param newLength the length of the copy to be returned
* @param newType the class of the copy to be returned
* @return a copy of the original array, truncated or padded with nulls
* to obtain the specified length
* @throws NegativeArraySizeException if <tt>newLength</tt> is negative
* @throws NullPointerException if <tt>original</tt> is null
* @throws ArrayStoreException if an element copied from
* <tt>original</tt> is not of a runtime type that can be stored in
* an array of class <tt>newType</tt>
* @since 1.6
*/
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
2、oid add(int index, E element)
list.add(1,"4");
System.out.println("-----------------------result-----------------------");
System.out.println(list);//[1, 4, 2, 3]
System.out.println("-----------------------result-----------------------");
實現源碼與add類似
/**
* Inserts the specified element at the specified position in this
* list. Shifts the element currently at that position (if any) and
* any subsequent elements to the right (adds one to their indices).
*
* @param index index at which the specified element is to be inserted
* @param element element to be inserted
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
3、addAll(Collection
List<String> lt = new ArrayList<>();
lt.add("4");
lt.add("5");
list.addAll(lt);
System.out.println("-----------------------result-----------------------");
System.out.println(list);//[1, 4, 2, 3, 4, 5]
System.out.println("-----------------------result-----------------------");
實現源碼
/**
* Appends all of the elements in the specified collection to the end of
* this list, in the order that they are returned by the
* specified collection's Iterator. The behavior of this operation is
* undefined if the specified collection is modified while the operation
* is in progress. (This implies that the behavior of this call is
* undefined if the specified collection is this list, and this
* list is nonempty.)
*
* @param c collection containing elements to be added to this list
* @return <tt>true</tt> if this list changed as a result of the call
* @throws NullPointerException if the specified collection is null
*/
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
4、 addAll(int index, Collection
list.addAll(4,lt);
System.out.println("-----------------------result-----------------------");
System.out.println(list);//[1, 4, 2, 3, 4, 5, 4, 5]
System.out.println("-----------------------result-----------------------");
實現源碼
/**
* Inserts all of the elements in the specified collection into this
* list, starting at the specified position. Shifts the element
* currently at that position (if any) and any subsequent elements to
* the right (increases their indices). The new elements will appear
* in the list in the order that they are returned by the
* specified collection's iterator.
*
* @param index index at which to insert the first element from the
* specified collection
* @param c collection containing elements to be added to this list
* @return <tt>true</tt> if this list changed as a result of the call
* @throws IndexOutOfBoundsException {@inheritDoc}
* @throws NullPointerException if the specified collection is null
*/
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
int numMoved = size - index;
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
5、 remove(int index);
list.remove(1);
System.out.println("-----------------------result-----------------------");
System.out.println(list);//[1, 2, 3, 4, 5, 4, 5]
System.out.println("-----------------------result-----------------------");
源碼實現
/**
* Removes the element at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their
* indices).
*
* @param index the index of the element to be removed
* @return the element that was removed from the list
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
/**
* Checks if the given index is in range. If not, throws an appropriate
* runtime exception. This method does *not* check if the index is
* negative: It is always used immediately prior to an array access,
* which throws an ArrayIndexOutOfBoundsException if index is negative.
*/
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
E elementData(int index) {
return (E) elementData[index];
}
6、 remove(Object o);
List<User> listUsers = new ArrayList<>();
User user1 = new User("小小");
User user2 = new User("塔基哥");
listUsers.add(user1);
listUsers.add(user2);
listUsers.remove(user1);
System.out.println("-----------------------result-----------------------");
System.out.println(listUsers+">>>>>>>>"+listUsers.get(0).getName());//[com.java.test.User@4f801c4]>>>>>>>>塔基哥
System.out.println("-----------------------result-----------------------");
源碼實現
/**
* 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
* <tt>i</tt> such that
* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>
* (if such an element exists). Returns <tt>true</tt> 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 <tt>true</tt> if this list contained the specified element
*/
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < 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 > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}
7、 T[] toArray(T[] a)
System.out.println("-----------------------result-----------------------");
String[] num_ary = list.toArray(new String[]{});
StringBuffer sf = new StringBuffer();
for(String num_str:num_ary){
if("".equals(sf.toString()))
sf.append(num_str);
else
sf.append(","+num_str);
}
System.out.println(list.toArray(num_ary)+">>>>>>>>["+sf.toString()+"]");//[Ljava.lang.String;@61bf61a0>>>>>>>>[1,2,3,4,5,4,5]
System.out.println("-----------------------result-----------------------");
源碼實現
/**
* Returns an array containing all of the elements in this list in proper
* sequence (from first to last element); the runtime type of the returned
* array is that of the specified array. If the list fits in the
* specified array, it is returned therein. Otherwise, a new array is
* allocated with the runtime type of the specified array and the size of
* this list.
*
* <p>If the list fits in the specified array with room to spare
* (i.e., the array has more elements than the list), the element in
* the array immediately following the end of the collection is set to
* <tt>null</tt>. (This is useful in determining the length of the
* list <i>only</i> if the caller knows that the list does not contain
* any null elements.)
*
* @param a the array into which the elements of the list are to
* be stored, if it is big enough; otherwise, a new array of the
* same runtime type is allocated for this purpose.
* @return an array containing the elements of the list
* @throws ArrayStoreException if the runtime type of the specified array
* is not a supertype of the runtime type of every element in
* this list
* @throws NullPointerException if the specified array is null
*/
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
if (a.length < size)
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
8、 contains(Object o);
System.out.println("-----------------------result-----------------------");
System.out.println(listUsers.contains(user2));//true
System.out.println("-----------------------result-----------------------");
源碼實現
/**
* Returns <tt>true</tt> if this list contains the specified element.
* More formally, returns <tt>true</tt> if and only if this list contains
* at least one element <tt>e</tt> such that
* <tt>(o==null ? e==null : o.equals(e))</tt>.
*
* @param o element whose presence in this list is to be tested
* @return <tt>true</tt> if this list contains the specified element
*/
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
/**
* Returns the index of the first occurrence of the specified element
* in this list, or -1 if this list does not contain the element.
* More formally, returns the lowest index <tt>i</tt> such that
* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
* or -1 if there is no such index.
*/
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
9、 containsAll(Collection
List<User> listUsersTemp = new ArrayList<>();
listUsersTemp.add(user2);
System.out.println("-----------------------result-----------------------");
System.out.println(listUsers.containsAll(listUsersTemp));//true
System.out.println("-----------------------result-----------------------");
源碼實現
/**
* {@inheritDoc}
*
* <p>This implementation iterates over the specified collection,
* checking each element returned by the iterator in turn to see
* if it's contained in this collection. If all elements are so
* contained <tt>true</tt> is returned, otherwise <tt>false</tt>.
*
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @see #contains(Object)
*/
public boolean containsAll(Collection<?> c) {
for (Object e : c)
if (!contains(e))
return false;
return true;
}
10、 subList(int fromIndex, int toIndex)
這個比較特殊 放在最後說
11、 e remove(int index);
System.out.println("-----------------------result-----------------------");
System.out.println("list.get(2)>>>>>>"+list.get(2));
String remove = list.remove(2);
System.out.println(remove);
System.out.println("-----------------------result-----------------------");
源碼
/**
* Removes the element at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their
* indices).
*
* @param index the index of the element to be removed
* @return the element that was removed from the list
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
12、 void clear()
System.out.println("-----------------------result-----------------------");
list.clear();
System.out.println(list.size());
System.out.println("-----------------------result-----------------------");
實現源碼
/**
* Removes all of the elements from this list. The list will
* be empty after this call returns.
*/
public void clear() {
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
其實看了上面的代碼可以發現ArrayList的操作基本上都是通過System.arraycopy()來實現的。
//src:源數組;
//srcPos:源數組要複製的起始位置;
//dest:目的數組;
//destPos:目的數組放置的起始位置;
//length:複製的長度。
System.arraycopy((Object src,int srcPos,Object dest,int destPos,int length)
現在重點來說subList 爲什麼會出現我的的測試例子裏面的那一幕,爲什麼我需要在使用subList方法後要重新包裝?
List<String> listSubList = new ArrayList<>(list.subList(1,3));
爲什麼不包裝的請開心 操作截取後的list對象會影響原來的list對象?
List<String> data = new ArrayList<>();
data.add("one");
data.add("two");
data.add("three");
data.add("four");
data.add("five");
List<String> listSubListTest = data.subList(2,4);
System.out.println("-----------------------result-----------------------");
System.out.println("-----------before-----------");
System.out.println("data>>>"+data);//data>>>[one, two, three, four, five]
System.out.println("listSubListTest>>>"+listSubListTest);//listSubListTest>>>[three, four]
System.out.println("-----------after-----------");
//神奇的事情發生了
listSubListTest.add("six");
System.out.println("data>>>"+data);//data>>>[one, two, three, four, six, five]
System.out.println("listSubListTest>>>"+listSubListTest);//listSubListTest>>>[three, four, six]
System.out.println("-----------------------result-----------------------");
說明:
這是因爲subList方法的實現時把當前對象的引用傳入了實現方法
subList傳入了this
return new SubList(this, 0, fromIndex, toIndex);
這樣截取後的對象的引用是截取之前的原list對象。這樣的話list對象就有了兩個引用,操作任何一個就能影響list對象。
這也是爲什麼在使用subList方法後需要重新包裝的原因重新包裝就會產生一個新的對象這樣操作,不會影響原對象。
/**
* Returns a view of the portion of this list between the specified
* {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. (If
* {@code fromIndex} and {@code toIndex} are equal, the returned list is
* empty.) The returned list is backed by this list, so non-structural
* changes in the returned list are reflected in this list, and vice-versa.
* The returned list supports all of the optional list operations.
*
* <p>This method eliminates the need for explicit range operations (of
* the sort that commonly exist for arrays). Any operation that expects
* a list can be used as a range operation by passing a subList view
* instead of a whole list. For example, the following idiom
* removes a range of elements from a list:
* <pre>
* list.subList(from, to).clear();
* </pre>
* Similar idioms may be constructed for {@link #indexOf(Object)} and
* {@link #lastIndexOf(Object)}, and all of the algorithms in the
* {@link Collections} class can be applied to a subList.
*
* <p>The semantics of the list returned by this method become undefined if
* the backing list (i.e., this list) is <i>structurally modified</i> in
* any way other than via the returned list. (Structural modifications are
* those that change the size of this list, or otherwise perturb it in such
* a fashion that iterations in progress may yield incorrect results.)
*
* @throws IndexOutOfBoundsException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
*/
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, 0, fromIndex, toIndex);
}
private class SubList extends AbstractList<E> implements RandomAccess {
private final AbstractList<E> parent;
private final int parentOffset;
private final int offset;
int size;
SubList(AbstractList<E> parent,
int offset, int fromIndex, int toIndex) {
this.parent = parent;
this.parentOffset = fromIndex;
this.offset = offset + fromIndex;
this.size = toIndex - fromIndex;
this.modCount = ArrayList.this.modCount;
}
public E set(int index, E e) {
rangeCheck(index);
checkForComodification();
E oldValue = ArrayList.this.elementData(offset + index);
ArrayList.this.elementData[offset + index] = e;
return oldValue;
}
public E get(int index) {
rangeCheck(index);
checkForComodification();
return ArrayList.this.elementData(offset + index);
}
public int size() {
checkForComodification();
return this.size;
}
public void add(int index, E e) {
rangeCheckForAdd(index);
checkForComodification();
parent.add(parentOffset + index, e);
this.modCount = parent.modCount;
this.size++;
}
public E remove(int index) {
rangeCheck(index);
checkForComodification();
E result = parent.remove(parentOffset + index);
this.modCount = parent.modCount;
this.size--;
return result;
}
protected void removeRange(int fromIndex, int toIndex) {
checkForComodification();
parent.removeRange(parentOffset + fromIndex,
parentOffset + toIndex);
this.modCount = parent.modCount;
this.size -= toIndex - fromIndex;
}
public boolean addAll(Collection<? extends E> c) {
return addAll(this.size, c);
}
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
int cSize = c.size();
if (cSize==0)
return false;
checkForComodification();
parent.addAll(parentOffset + index, c);
this.modCount = parent.modCount;
this.size += cSize;
return true;
}
public Iterator<E> iterator() {
return listIterator();
}
public ListIterator<E> listIterator(final int index) {
checkForComodification();
rangeCheckForAdd(index);
final int offset = this.offset;
return new ListIterator<E>() {
int cursor = index;
int lastRet = -1;
int expectedModCount = ArrayList.this.modCount;
public boolean hasNext() {
return cursor != SubList.this.size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= SubList.this.size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[offset + (lastRet = i)];
}
public boolean hasPrevious() {
return cursor != 0;
}
@SuppressWarnings("unchecked")
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[offset + (lastRet = i)];
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor - 1;
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
SubList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(offset + lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void add(E e) {
checkForComodification();
try {
int i = cursor;
SubList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (expectedModCount != ArrayList.this.modCount)
throw new ConcurrentModificationException();
}
};
}
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, offset, fromIndex, toIndex);
}
private void rangeCheck(int index) {
if (index < 0 || index >= this.size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void rangeCheckForAdd(int index) {
if (index < 0 || index > this.size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+this.size;
}
private void checkForComodification() {
if (ArrayList.this.modCount != this.modCount)
throw new ConcurrentModificationException();
}
}