JDK7集合框架原始碼學習-ArrayList(4)SubList
原始碼鎮樓
ArrayList的subList方法,首先呼叫subListRangeCheck方法做了一個範圍檢查.
然後建立並返回了一個SubList的內部類物件.
仔細對比SubList和ArrayList的定義.
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
private class SubList extends AbstractList<E> implements RandomAccess
他們同樣繼承了AbstractList,並實現了RandomAccess標記介面.
而AbstractList是一個抽象類,除了一些抽象方法,還有一些方法乾脆沒有實現.
比如:
在建立SubList內部類的時候,
new SubList(this, 0, fromIndex, toIndex);
實際上將外部的ArrayList物件,傳入了內部類作為一個資料成員,即 AbstractList parent
並且記錄了偏移量和Size等資訊.
SubList的方法呼叫,使用了兩種方式
1.因為內部類可以訪問外部類的方法和屬性,所以一些操作直接使用外部類的方法
2.由於內部類AbstractList parent指向外部類的物件,有一些操作呼叫parent的方法,透過多型性呼叫了外部類的方法.
程式碼風格似乎不太統一..
add和remove都是呼叫抽象類的方法,透過多型性呼叫了ArrayList的方法
而get和set方法,又是透過內部類可以直接訪問外部類的特性.
有點意思.
- public List<E> subList(int fromIndex, int toIndex) {
- subListRangeCheck(fromIndex, toIndex, size);
- return new SubList(this, 0, fromIndex, toIndex);
- }
- static void subListRangeCheck(int fromIndex, int toIndex, int size) {
- if (fromIndex < 0)
- throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
- if (toIndex > size)
- throw new IndexOutOfBoundsException("toIndex = " + toIndex);
- if (fromIndex > toIndex)
- throw new IllegalArgumentException("fromIndex(" + fromIndex +
- ") > toIndex(" + 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();
- }
- }
ArrayList的subList方法,首先呼叫subListRangeCheck方法做了一個範圍檢查.
然後建立並返回了一個SubList的內部類物件.
仔細對比SubList和ArrayList的定義.
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
private class SubList extends AbstractList<E> implements RandomAccess
他們同樣繼承了AbstractList,並實現了RandomAccess標記介面.
而AbstractList是一個抽象類,除了一些抽象方法,還有一些方法乾脆沒有實現.
比如:
- abstract public E get(int index);
- public E set(int index, E element) {
- throw new UnsupportedOperationException();
- }
- public void add(int index, E element) {
- throw new UnsupportedOperationException();
- }
- public E remove(int index) {
- throw new UnsupportedOperationException();
- }
在建立SubList內部類的時候,
new SubList(this, 0, fromIndex, toIndex);
實際上將外部的ArrayList物件,傳入了內部類作為一個資料成員,即 AbstractList parent
並且記錄了偏移量和Size等資訊.
- 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;
- }
SubList的方法呼叫,使用了兩種方式
1.因為內部類可以訪問外部類的方法和屬性,所以一些操作直接使用外部類的方法
2.由於內部類AbstractList parent指向外部類的物件,有一些操作呼叫parent的方法,透過多型性呼叫了外部類的方法.
程式碼風格似乎不太統一..
add和remove都是呼叫抽象類的方法,透過多型性呼叫了ArrayList的方法
- 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;
- }
而get和set方法,又是透過內部類可以直接訪問外部類的特性.
- 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);
- }
有點意思.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-2121834/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 集合框架原始碼學習之ArrayList框架原始碼
- Java集合原始碼學習(2)ArrayListJava原始碼
- Java 集合框架------ArrayList原始碼分析Java框架原始碼
- 再說Java集合,subList之於ArrayListJava
- 集合框架原始碼學習之LinkedList框架原始碼
- 集合-ArrayList 原始碼解析原始碼
- Java集合原始碼學習(4)HashSetJava原始碼
- JAVA集合:ArrayList原始碼分析Java原始碼
- 【Java集合】ArrayList原始碼分析Java原始碼
- 集合原始碼分析[3]-ArrayList 原始碼分析原始碼
- Java集合原始碼剖析——ArrayList原始碼剖析Java原始碼
- Java容器原始碼學習--ArrayList原始碼分析Java原始碼
- Java集合之ArrayList原始碼解析Java原始碼
- java集合原始碼分析(三):ArrayListJava原始碼
- 集合框架原始碼學習之HashMap(JDK1.8)框架原始碼HashMapJDK
- JAVA ArrayList集合底層原始碼分析Java原始碼
- Java集合框架(一)-ArrayListJava框架
- 集合框架2- ArrayList框架
- 死磕 java集合之ArrayList原始碼分析Java原始碼
- Java集合-ArrayList原始碼解析-JDK1.8Java原始碼JDK
- java集合學習(一):詳解ArrayListJava
- 純手寫Arraylist集合框架框架
- Java 集合 ArrayList 原始碼分析(帶著問題看原始碼)Java原始碼
- 【Java集合原始碼剖析】Java集合框架Java原始碼框架
- Java類集框架 —— ArrayList原始碼分析Java框架原始碼
- Java集合原始碼學習(5)HashMapJava原始碼HashMap
- Java集合原始碼學習(3)LinkedListJava原始碼
- Java集合原始碼學習(1)介面Java原始碼
- 還在深入瞭解集合框架(ArrayList、LinkedList)原始碼?先看看這篇文章吧框架原始碼
- Okio 框架原始碼學習框架原始碼
- Java集合框架學習Java框架
- JAVA集合:常見Set原始碼學習Java原始碼
- Java容器類框架分析(1)ArrayList原始碼分析Java框架原始碼
- ArrayList分析2 :Itr、ListIterator以及SubList中的坑
- [原始碼分析]ArrayList原始碼
- ArrayList 原始碼分析原始碼
- ArrayList原始碼解析原始碼
- ArrayList原始碼分析原始碼
- 設計模式(十七)——迭代器模式(ArrayList 集合應用原始碼分析)設計模式原始碼