1 public List subList(int fromIndex, inttoIndex) {2 //检查参数fromIndex和toIndex是否合法
3 subListRangeCheck(fromIndex, toIndex, size);4 //创建一个SubList对象
5 return new SubList(this, 0, fromIndex, toIndex);6 }7
8 static void subListRangeCheck(int fromIndex, int toIndex, intsize) {9 //起始位置fromIndex小于0,则抛出异常
10 if (fromIndex < 0)11 throw new IndexOutOfBoundsException("fromIndex = " +fromIndex);12 //终止位置toIndex大于列表中元素个数size,则抛出异常
13 if (toIndex >size)14 throw new IndexOutOfBoundsException("toIndex = " +toIndex);15 //起始位置fromIndex 大于 终止位置toIndex,则抛出异常
16 if (fromIndex >toIndex)17 throw new IllegalArgumentException("fromIndex(" + fromIndex +") > toIndex(" + toIndex + ")");18 }19
20 /*
21 内部类,为了配合subList方法22 */
23 private class SubList extends AbstractList implementsRandomAccess {24 private final AbstractListparent;25 private final intparentOffset;26 private final intoffset;27 intsize;28 //构造方法
29 SubList(AbstractListparent,30 int offset, int fromIndex, inttoIndex) {31 this.parent =parent;32 this.parentOffset =fromIndex;33 this.offset = offset +fromIndex;34 this.size = toIndex -fromIndex;35 this.modCount = ArrayList.this.modCount;36 }37
38 public E set(intindex, E e) {39 rangeCheck(index);40 checkForComodification();41 E oldValue = ArrayList.this.elementData(offset +index);42 ArrayList.this.elementData[offset + index] =e;43 returnoldValue;44 }45
46 public E get(intindex) {47 rangeCheck(index);48 checkForComodification();49 return ArrayList.this.elementData(offset +index);50 }51
52 public intsize() {53 checkForComodification();54 return this.size;55 }56
57 public void add(intindex, E e) {58 rangeCheckForAdd(index);59 checkForComodification();60 parent.add(parentOffset +index, e);61 this.modCount =parent.modCount;62 this.size++;63 }64
65 public E remove(intindex) {66 rangeCheck(index);67 checkForComodification();68 E result = parent.remove(parentOffset +index);69 this.modCount =parent.modCount;70 this.size--;71 returnresult;72 }73
74 protected void removeRange(int fromIndex, inttoIndex) {75 checkForComodification();76 parent.removeRange(parentOffset +fromIndex,77 parentOffset +toIndex);78 this.modCount =parent.modCount;79 this.size -= toIndex -fromIndex;80 }81
82 public boolean addAll(Collection extends E>c) {83 return addAll(this.size, c);84 }85
86 public boolean addAll(int index, Collection extends E>c) {87 rangeCheckForAdd(index);88 int cSize =c.size();89 if (cSize==0)90 return false;91
92 checkForComodification();93 parent.addAll(parentOffset +index, c);94 this.modCount =parent.modCount;95 this.size +=cSize;96 return true;97 }98
99 public Iteratoriterator() {100 returnlistIterator();101 }102
103 public ListIterator listIterator(final intindex) {104 checkForComodification();105 rangeCheckForAdd(index);106 final int offset = this.offset;107
108 return new ListIterator() {109 int cursor =index;110 int lastRet = -1;111 int expectedModCount = ArrayList.this.modCount;112
113 public booleanhasNext() {114 return cursor != SubList.this.size;115 }116
117 @SuppressWarnings("unchecked")118 publicE next() {119 checkForComodification();120 int i =cursor;121 if (i >= SubList.this.size)122 throw newNoSuchElementException();123 Object[] elementData = ArrayList.this.elementData;124 if (offset + i >=elementData.length)125 throw newConcurrentModificationException();126 cursor = i + 1;127 return (E) elementData[offset + (lastRet =i)];128 }129
130 public booleanhasPrevious() {131 return cursor != 0;132 }133
134 @SuppressWarnings("unchecked")135 publicE previous() {136 checkForComodification();137 int i = cursor - 1;138 if (i < 0)139 throw newNoSuchElementException();140 Object[] elementData = ArrayList.this.elementData;141 if (offset + i >=elementData.length)142 throw newConcurrentModificationException();143 cursor =i;144 return (E) elementData[offset + (lastRet =i)];145 }146
147 public intnextIndex() {148 returncursor;149 }150
151 public intpreviousIndex() {152 return cursor - 1;153 }154
155 public voidremove() {156 if (lastRet < 0)157 throw newIllegalStateException();158 checkForComodification();159
160 try{161 SubList.this.remove(lastRet);162 cursor =lastRet;163 lastRet = -1;164 expectedModCount = ArrayList.this.modCount;165 } catch(IndexOutOfBoundsException ex) {166 throw newConcurrentModificationException();167 }168 }169
170 public voidset(E e) {171 if (lastRet < 0)172 throw newIllegalStateException();173 checkForComodification();174
175 try{176 ArrayList.this.set(offset +lastRet, e);177 } catch(IndexOutOfBoundsException ex) {178 throw newConcurrentModificationException();179 }180 }181
182 public voidadd(E e) {183 checkForComodification();184
185 try{186 int i =cursor;187 SubList.this.add(i, e);188 cursor = i + 1;189 lastRet = -1;190 expectedModCount = ArrayList.this.modCount;191 } catch(IndexOutOfBoundsException ex) {192 throw newConcurrentModificationException();193 }194 }195
196 final voidcheckForComodification() {197 if (expectedModCount != ArrayList.this.modCount)198 throw newConcurrentModificationException();199 }200 };201 }202
203 public List subList(int fromIndex, inttoIndex) {204 subListRangeCheck(fromIndex, toIndex, size);205 return new SubList(this, offset, fromIndex, toIndex);206 }207
208 private void rangeCheck(intindex) {209 if (index < 0 || index >= this.size)210 throw newIndexOutOfBoundsException(outOfBoundsMsg(index));211 }212
213 private void rangeCheckForAdd(intindex) {214 if (index < 0 || index > this.size)215 throw newIndexOutOfBoundsException(outOfBoundsMsg(index));216 }217
218 private String outOfBoundsMsg(intindex) {219 return "Index: "+index+", Size: "+this.size;220 }221
222 private voidcheckForComodification() {223 if (ArrayList.this.modCount != this.modCount)224 throw newConcurrentModificationException();225 }226 }