一、JDK中ArrayList是如何实现的
1、先看下ArrayList从上而下的层次图:
说明:
从图中可以看出,ArrayList只是最下层的实现类,集合的规则和扩展都是AbstractList、List、Collection等上层的接口所设定的,而ArrayList实现或继承了上层的规则,然后重新或扩展来处理集合中的数据。
2、看看接口:Iterable<E>中都定义了那些规则?
JDK1.8中的源码:
1 package java.lang;
2
3 import java.util.Iterator;
4 import java.util.Objects;
5 import java.util.Spliterator;
6 import java.util.Spliterators;
7 import java.util.function.Consumer;
8 public interface Iterable<T> {//实现这个接口允许对象成为 "foreach" 语句的目标。
9 Iterator<T> iterator();
10 default void forEach(Consumer<? super T> action) {
11 Objects.requireNonNull(action);
12 for (T t : this) {
13 action.accept(t);
14 }
15 }
16 default Spliterator<T> spliterator() {
17 return Spliterators.spliteratorUnknownSize(iterator(), 0);
18 }
19 }
这里说明一下:
(1)Consumer<? super T> action 可以理解为:实现了Consumer接口的实现类对象。
(2)accept(T t) T 是每一次forEach方法处理的数据类型,t是数据
(3)spliterator():Spliterator
(splitable iterator可分割迭代器)接口是Java为了并行遍历数据源中的元素而设计的迭代器。也就是收JDK1.8版本已经支持多核并发处理集合中的数据了,你只需要告诉JDK你要做什么并行任务,关注业务本身,至于如何并行,怎么并行效率最高,就交给JDK自己去思考和优化速度了。
简单举个forEach的例子:
1 package com.xfwl.test;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.function.Consumer;
6 @SuppressWarnings("unchecked")
7 public class Test2 {
8 public static void main(String[] args) {
9 List alist=new ArrayList();
10 alist.add("1");
11 alist.forEach(new T());
12 }
13 /**
14 * Consumer接口测试实现类T
15 * @param <E>
16 */
17 static class T implements Consumer{
18 public T(){}
19 public void accept(Object e) {
20 System.out.println("当前数据:"+e);
21 }
22 public Consumer andThen(Consumer after) {
23 // TODO Auto-generated method stub
24 return null;
25 }
26 }
27 }
运行结果:
当前数据:1
总结一下:
(1)接口Iterable,定义了遍历集合中的数据的方法:forEach(),这个方法需要一个实现了Consumer接口的参数;
(2)接口Iterable,定义了一个可以实现并发的迭代器,具体如何实现和优化交给jdk自己处理,我们只负责使用集合即可。
3、看看接口:Collection<E>中定义了那些规则?
JDK1.8中的源码:
1 package java.util;
2 import java.util.function.Predicate;
3 import java.util.stream.Stream;
4 import java.util.stream.StreamSupport;
5
6 public interface Collection<E> extends Iterable<E> {
7 int size(); //获取集合元素总数
8 boolean isEmpty(); //判断集合是否非空
9 boolean contains(Object o); //判断集合是否包含指定元素
10 Iterator<E> iterator(); //获取迭代器
11 Object[] toArray(); //把集合转化成Object类型数组对象
12 <T> T[] toArray(T[] a); //把集合转化成指定T类型数组对象
13 boolean add(E e); //添加数据到集合
14 boolean remove(Object o); //从集合中移除数据
15 boolean containsAll(Collection<?> c); //集合是否包含另一个集合
16 boolean addAll(Collection<? extends E> c); //集合添加另外一个集合
17 boolean removeAll(Collection<?> c); //集合中移除另外一个集合中的内容
18 default boolean removeIf(Predicate<? super E> filter) {//JDK1.8开始加入的方法,按指定条件移除集合中的信息
19 Objects.requireNonNull(filter);
20 boolean removed = false;
21 final Iterator<E> each = iterator();
22 while (each.hasNext()) {
23 if (filter.test(each.next())) {
24 each.remove();
25 removed = true;
26 }
27 }
28 return removed;
29 }
30 boolean retainAll(Collection<?> c); //移除此 collection 中未包含在指定 collection 中的所有元素
31 void clear(); //清除集合中的信息
32 boolean equals(Object o); //比较此 collection 与指定对象是否相等。
33 int hashCode(); //返回此 collection 的哈希码值。
34 @Override
35 default Spliterator<E> spliterator() { //JDK1.8开始新加入的方法,返回当前集合的并发迭代器
36 return Spliterators.spliterator(this, 0);
37 }
38 default Stream<E> stream() { //JDK1.8开始新加入的方法,通过传入并发迭代器,来使用stream过滤集合数据
39 return StreamSupport.stream(spliterator(), false);//返回的流是顺序的
40 }
41 default Stream<E> parallelStream() { //JDK1.8开始新加入的方法,通过传入并发迭代器,来使用stream过滤集合数据
42 return StreamSupport.stream(spliterator(), true);//返回的流是并行的
43 }
44 }
这里说明一下:
(1)JDK8版本中,接口中可以定义方法的实现了,即方法可以定义方法体了。
(2)Collection中定义了一些针对集合数据的添加,删除,判空,是否存在,整块集合的包含+移除等操作,以及JDK1.8开始新增的方法:removeIf()和spliterator(),stream()以及parallelStream()方法。
简单举个stream()的例子:
1 package com.xfwl.test;
2
3 import java.util.Arrays;
4 import java.util.List;
5 import java.util.function.Consumer;
6 import java.util.stream.Collectors;
7 @SuppressWarnings("unchecked")
8 public class Test2 {
9 public static void main(String[] args) {
10 List<Integer> alist=Arrays.asList(1,2,3,4,5,6,7,8,9,10);
11 alist=alist.stream().filter(s -> (s>5)).collect(Collectors.toList());//lumbda表达式
12 for(int i:alist){ 13 System.out.println(i); 14 } 15 16 } 17 }
运行结果:
6
7
8
9
10
继续修改代码,举个removeIf()的例子:
1 package com.xfwl.test;
2
3 import java.util.Arrays;
4 import java.util.List;
5 import java.util.function.Consumer;
6 import java.util.stream.Collectors;
7 @SuppressWarnings("unchecked")
8 public class Test2 {
9 public static void main(String[] args) {
10 List<Integer> alist=Arrays.asList(1,2,3,4,5,6,7,8,9,10);
11 alist=alist.stream().filter(s -> (s>5)).collect(Collectors.toList());//lumbda表达式
12 alist.removeIf(s->s==10);
13 for(int i:alist){
14 System.out.println(i);
15 }
16 }
17 }
运行结果:
6
7
8
9
4、看看抽象类:AbstractCollection<E>中定义了那些规则?
JDK1.8中的源码


1 package java.util;
2 public abstract class AbstractCollection<E> implements Collection<E> {
3 protected AbstractCollection() {
4 }
5 public abstract Iterator<E> iterator();
6
7 public abstract int size();
8
9 public boolean isEmpty() {
10 return size() == 0;
11 }
12 public boolean contains(Object o) {
13 Iterator<E> it = iterator();
14 if (o==null) {
15 while (it.hasNext())
16 if (it.next()==null)
17 return true;
18 } else {
19 while (it.hasNext())
20 if (o.equals(it.next()))
21 return true;
22 }
23 return false;
24 }
25 public Object[] toArray() {
26 // Estimate size of array; be prepared to see more or fewer elements
27 Object[] r = new Object[size()];
28 Iterator<E> it = iterator();
29 for (int i = 0; i < r.length; i++) {
30 if (! it.hasNext()) // fewer elements than expected
31 return Arrays.copyOf(r, i);
32 r[i] = it.next();
33 }
34 return it.hasNext() ? finishToArray(r, it) : r;
35 }
36 @SuppressWarnings("unchecked")
37 public <T> T[] toArray(T[] a) {
38 // Estimate size of array; be prepared to see more or fewer elements
39 int size = size();
40 T[] r = a.length >= size ? a :
41 (T[])java.lang.reflect.Array
42 .newInstance(a.getClass().getComponentType(), size);
43 Iterator<E> it = iterator();
44
45 for (int i = 0; i < r.length; i++) {
46 if (! it.hasNext()) { // fewer elements than expected
47 if (a == r) {
48 r[i] = null; // null-terminate
49 } else if (a.length < i) {
50 return Arrays.copyOf(r, i);
51 } else {
52 System.arraycopy(r, 0, a, 0, i);
53 if (a.length > i) {
54 a[i] = null;
55 }
56 }
57 return a;
58 }
59 r[i] = (T)it.next();
60 }
61 // more elements than expected
62 return it.hasNext() ? finishToArray(r, it) : r;
63 }
64
65 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
66 @SuppressWarnings("unchecked")
67 private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
68 int i = r.length;
69 while (it.hasNext()) {
70 int cap = r.length;
71 if (i == cap) {
72 int newCap = cap + (cap >> 1) + 1;
73 // overflow-conscious code
74 if (newCap - MAX_ARRAY_SIZE > 0)
75 newCap = hugeCapacity(cap + 1);
76 r = Arrays.copyOf(r, newCap);
77 }
78 r[i++] = (T)it.next();
79 }
80 // trim if overallocated
81 return (i == r.length) ? r : Arrays.copyOf(r, i);
82 }
83
84 private static int hugeCapacity(int minCapacity) {
85 if (minCapacity < 0) // overflow
86 throw new OutOfMemoryError
87 ("Required array size too large");
88 return (minCapacity > MAX_ARRAY_SIZE) ?
89 Integer.MAX_VALUE :
90 MAX_ARRAY_SIZE;
91 }
92 public boolean add(E e) {
93 throw new UnsupportedOperationException();
94 }
95 public boolean remove(Object o) {
96 Iterator<E> it = iterator();
97 if (o==null) {
98 while (it.hasNext()) {
99 if (it.next()==null) {
100 it.remove();
101 return true;
102 }
103 }
104 } else {
105 while (it.hasNext()) {
106 if (o.equals(it.next())) {
107 it.remove();
108 return true;
109 }
110 }
111 }
112 return false;
113 }
114 public boolean containsAll(Collection<?> c) {
115 for (Object e : c)
116 if (!contains(e))
117 return false;
118 return true;
119 }
120 public boolean addAll(Collection<? extends E> c) {
121 boolean modified = false;
122 for (E e : c)
123 if (add(e))
124 modified = true;
125 return modified;
126 }
127 public boolean removeAll(Collection<?> c) {
128 Objects.requireNonNull(c);
129 boolean modified = false;
130 Iterator<?> it = iterator();
131 while (it.hasNext()) {
132 if (c.contains(it.next())) {
133 it.remove();
134 modified = true;
135 }
136 }
137 return modified;
138 }
139 public boolean retainAll(Collection<?> c) {
140 Objects.requireNonNull(c);
141 boolean modified = false;
142 Iterator<E> it = iterator();
143 while (it.hasNext()) {
144 if (!c.contains(it.next())) {
145 it.remove();
146 modified = true;
147 }
148 }
149 return modified;
150 }
151 public void clear() {
152 Iterator<E> it = iterator();
153 while (it.hasNext()) {
154 it.next();
155 it.remove();
156 }
157 }
158 public String toString() {
159 Iterator<E> it = iterator();
160 if (! it.hasNext())
161 return "[]";
162
163 StringBuilder sb = new StringBuilder();
164 sb.append('[');
165 for (;;) {
166 E e = it.next();
167 sb.append(e == this ? "(this Collection)" : e);
168 if (! it.hasNext())
169 return sb.append(']').toString();
170 sb.append(',').append(' ');
171 }
172 }
173
174 }
说明一下:
(1)整体上来看,抽象类:AbstractCollection<E>实现了Collection接口,并且定义了接口中没有实现的方法体。
(2)其中的: public abstract Iterator<E> iterator(); 依然是沿用之前jdk版本的使用方式,当前抽象类没有给出具体的实现,在另外一个抽象类AbstractList中给出了具体实现:
1 public Iterator<E> iterator() {
2 return new Itr();
3 }
那么其中:new Itr()拿到的到底是什么呢?
继续贴出jdk中的源码:
1 private class Itr implements Iterator<E> {
2 int cursor = 0; //下一个元素的索引下标
3 int lastRet = -1; //上一个被调用的元素下标
4 int expectedModCount = modCount;
5 public boolean hasNext() {
6 return cursor != size();
7 }
8
9 public E next() { //返回下一个元素
10 checkForComodification();
11 try {
12 int i = cursor;
13 E next = get(i);
14 lastRet = i;
15 cursor = i + 1;
16 return next;
17 } catch (IndexOutOfBoundsException e) {
18 checkForComodification();
19 throw new NoSuchElementException();
20 }
21 }
22
23 public void remove() { //移除元素
24 if (lastRet < 0)
25 throw new IllegalStateException();
26 checkForComodification();
27
28 try {
29 AbstractList.this.remove(lastRet);
30 if (lastRet < cursor)
31 cursor--;
32 lastRet = -1;
33 expectedModCount = modCount;
34 } catch (IndexOutOfBoundsException e) {
35 throw new ConcurrentModificationException();
36 }
37 }
38
39 final void checkForComodification() {
40 if (modCount != expectedModCount)
41 throw new ConcurrentModificationException();
42 }
43 }
总结一下:
到目前为止,我们知道,如果只是想简单地获取集合的迭代器(非并行),可直接调用集合的iterator()方法即可,但是如果想要调用几何的并发的迭代器,则需要换一个JDK1.8新增进去的方法:
1 default Stream<E> stream() { //JDK1.8开始新加入的方法,通过传入并发迭代器,来使用stream过滤集合数据
2 return StreamSupport.stream(spliterator(), false);//返回的流是顺序的
3 }
4 default Stream<E> parallelStream() { //JDK1.8开始新加入的方法,通过传入并发迭代器,来使用stream过滤集合数据
5 return StreamSupport.stream(spliterator(), true);//返回的流是并行的
6 }
5、看看抽象类:AbstractList<E>中定义了那些规则?
贴上JDK1.8中的源码:


1 package java.util;
2 public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
3
4 protected AbstractList() {
5 }
6 public boolean add(E e) {
7 add(size(), e);
8 return true;
9 }
10
11 abstract public E get(int index);
12
13
14 public E set(int index, E element) {
15 throw new UnsupportedOperationException();
16 }
17 public void add(int index, E element) {
18 throw new UnsupportedOperationException();
19 }
20
21 public E remove(int index) {
22 throw new UnsupportedOperationException();
23 }
24 public int indexOf(Object o) {
25 ListIterator<E> it = listIterator();
26 if (o==null) {
27 while (it.hasNext())
28 if (it.next()==null)
29 return it.previousIndex();
30 } else {
31 while (it.hasNext())
32 if (o.equals(it.next()))
33 return it.previousIndex();
34 }
35 return -1;
36 }
37 public int lastIndexOf(Object o) {
38 ListIterator<E> it = listIterator(size());
39 if (o==null) {
40 while (it.hasPrevious())
41 if (it.previous()==null)
42 return it.nextIndex();
43 } else {
44 while (it.hasPrevious())
45 if (o.equals(it.previous()))
46 return it.nextIndex();
47 }
48 return -1;
49 }
50
51 public void clear() {
52 removeRange(0, size());
53 }
54 public boolean addAll(int index, Collection<? extends E> c) {
55 rangeCheckForAdd(index);
56 boolean modified = false;
57 for (E e : c) {
58 add(index++, e);
59 modified = true;
60 }
61 return modified;
62 }
63 public Iterator<E> iterator() {
64 return new Itr();
65 }
66 public ListIterator<E> listIterator() {
67 return listIterator(0);
68 }
69 public ListIterator<E> listIterator(final int index) {
70 rangeCheckForAdd(index);
71
72 return new ListItr(index);
73 }
74
75 private class Itr implements Iterator<E> {
76
77 int cursor = 0;
78
79
80 int lastRet = -1;
81
82
83 int expectedModCount = modCount;
84
85 public boolean hasNext() {
86 return cursor != size();
87 }
88
89 public E next() {
90 checkForComodification();
91 try {
92 int i = cursor;
93 E next = get(i);
94 lastRet = i;
95 cursor = i + 1;
96 return next;
97 } catch (IndexOutOfBoundsException e) {
98 checkForComodification();
99 throw new NoSuchElementException();
100 }
101 }
102
103 public void remove() {
104 if (lastRet < 0)
105 throw new IllegalStateException();
106 checkForComodification();
107
108 try {
109 AbstractList.this.remove(lastRet);
110 if (lastRet < cursor)
111 cursor--;
112 lastRet = -1;
113 expectedModCount = modCount;
114 } catch (IndexOutOfBoundsException e) {
115 throw new ConcurrentModificationException();
116 }
117 }
118
119 final void checkForComodification() {
120 if (modCount != expectedModCount)
121 throw new ConcurrentModificationException();
122 }
123 }
124
125 private class ListItr extends Itr implements ListIterator<E> {
126 ListItr(int index) {
127 cursor = index;
128 }
129
130 public boolean hasPrevious() {
131 return cursor != 0;
132 }
133
134 public E previous() {
135 checkForComodification();
136 try {
137 int i = cursor - 1;
138 E previous = get(i);
139 lastRet = cursor = i;
140 return previous;
141 } catch (IndexOutOfBoundsException e) {
142 checkForComodification();
143 throw new NoSuchElementException();
144 }
145 }
146
147 public int nextIndex() {
148 return cursor;
149 }
150
151 public int previousIndex() {
152 return cursor-1;
153 }
154
155 public void set(E e) {
156 if (lastRet < 0)
157 throw new IllegalStateException();
158 checkForComodification();
159
160 try {
161 AbstractList.this.set(lastRet, e);
162 expectedModCount = modCount;
163 } catch (IndexOutOfBoundsException ex) {
164 throw new ConcurrentModificationException();
165 }
166 }
167
168 public void add(E e) {
169 checkForComodification();
170
171 try {
172 int i = cursor;
173 AbstractList.this.add(i, e);
174 lastRet = -1;
175 cursor = i + 1;
176 expectedModCount = modCount;
177 } catch (IndexOutOfBoundsException ex) {
178 throw new ConcurrentModificationException();
179 }
180 }
181 }
182 public List<E> subList(int fromIndex, int toIndex) {
183 return (this instanceof RandomAccess ?
184 new RandomAccessSubList<>(this, fromIndex, toIndex) :
185 new SubList<>(this, fromIndex, toIndex));
186 }
187 public boolean equals(Object o) {
188 if (o == this)
189 return true;
190 if (!(o instanceof List))
191 return false;
192
193 ListIterator<E> e1 = listIterator();
194 ListIterator<?> e2 = ((List<?>) o).listIterator();
195 while (e1.hasNext() && e2.hasNext()) {
196 E o1 = e1.next();
197 Object o2 = e2.next();
198 if (!(o1==null ? o2==null : o1.equals(o2)))
199 return false;
200 }
201 return !(e1.hasNext() || e2.hasNext());
202 }
203 public int hashCode() {
204 int hashCode = 1;
205 for (E e : this)
206 hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
207 return hashCode;
208 }
209 protected void removeRange(int fromIndex, int toIndex) {
210 ListIterator<E> it = listIterator(fromIndex);
211 for (int i=0, n=toIndex-fromIndex; i<n; i++) {
212 it.next();
213 it.remove();
214 }
215 }
216 protected transient int modCount = 0;
217
218 private void rangeCheckForAdd(int index) {
219 if (index < 0 || index > size())
220 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
221 }
222
223 private String outOfBoundsMsg(int index) {
224 return "Index: "+index+", Size: "+size();
225 }
226 }
227
228 class SubList<E> extends AbstractList<E> {
229 private final AbstractList<E> l;
230 private final int offset;
231 private int size;
232
233 SubList(AbstractList<E> list, int fromIndex, int toIndex) {
234 if (fromIndex < 0)
235 throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
236 if (toIndex > list.size())
237 throw new IndexOutOfBoundsException("toIndex = " + toIndex);
238 if (fromIndex > toIndex)
239 throw new IllegalArgumentException("fromIndex(" + fromIndex +
240 ") > toIndex(" + toIndex + ")");
241 l = list;
242 offset = fromIndex;
243 size = toIndex - fromIndex;
244 this.modCount = l.modCount;
245 }
246
247 public E set(int index, E element) {
248 rangeCheck(index);
249 checkForComodification();
250 return l.set(index+offset, element);
251 }
252
253 public E get(int index) {
254 rangeCheck(index);
255 checkForComodification();
256 return l.get(index+offset);
257 }
258
259 public int size() {
260 checkForComodification();
261 return size;
262 }
263
264 public void add(int index, E element) {
265 rangeCheckForAdd(index);
266 checkForComodification();
267 l.add(index+offset, element);
268 this.modCount = l.modCount;
269 size++;
270 }
271
272 public E remove(int index) {
273 rangeCheck(index);
274 checkForComodification();
275 E result = l.remove(index+offset);
276 this.modCount = l.modCount;
277 size--;
278 return result;
279 }
280
281 protected void removeRange(int fromIndex, int toIndex) {
282 checkForComodification();
283 l.removeRange(fromIndex+offset, toIndex+offset);
284 this.modCount = l.modCount;
285 size -= (toIndex-fromIndex);
286 }
287
288 public boolean addAll(Collection<? extends E> c) {
289 return addAll(size, c);
290 }
291
292 public boolean addAll(int index, Collection<? extends E> c) {
293 rangeCheckForAdd(index);
294 int cSize = c.size();
295 if (cSize==0)
296 return false;
297
298 checkForComodification();
299 l.addAll(offset+index, c);
300 this.modCount = l.modCount;
301 size += cSize;
302 return true;
303 }
304
305 public Iterator<E> iterator() {
306 return listIterator();
307 }
308
309 public ListIterator<E> listIterator(final int index) {
310 checkForComodification();
311 rangeCheckForAdd(index);
312
313 return new ListIterator<E>() {
314 private final ListIterator<E> i = l.listIterator(index+offset);
315
316 public boolean hasNext() {
317 return nextIndex() < size;
318 }
319
320 public E next() {
321 if (hasNext())
322 return i.next();
323 else
324 throw new NoSuchElementException();
325 }
326
327 public boolean hasPrevious() {
328 return previousIndex() >= 0;
329 }
330
331 public E previous() {
332 if (hasPrevious())
333 return i.previous();
334 else
335 throw new NoSuchElementException();
336 }
337
338 public int nextIndex() {
339 return i.nextIndex() - offset;
340 }
341
342 public int previousIndex() {
343 return i.previousIndex() - offset;
344 }
345
346 public void remove() {
347 i.remove();
348 SubList.this.modCount = l.modCount;
349 size--;
350 }
351
352 public void set(E e) {
353 i.set(e);
354 }
355
356 public void add(E e) {
357 i.add(e);
358 SubList.this.modCount = l.modCount;
359 size++;
360 }
361 };
362 }
363
364 public List<E> subList(int fromIndex, int toIndex) {
365 return new SubList<>(this, fromIndex, toIndex);
366 }
367
368 private void rangeCheck(int index) {
369 if (index < 0 || index >= size)
370 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
371 }
372
373 private void rangeCheckForAdd(int index) {
374 if (index < 0 || index > size)
375 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
376 }
377
378 private String outOfBoundsMsg(int index) {
379 return "Index: "+index+", Size: "+size;
380 }
381
382 private void checkForComodification() {
383 if (this.modCount != l.modCount)
384 throw new ConcurrentModificationException();
385 }
386 }
387
388 class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
389 RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) {
390 super(list, fromIndex, toIndex);
391 }
392
393 public List<E> subList(int fromIndex, int toIndex) {
394 return new RandomAccessSubList<>(this, fromIndex, toIndex);
395 }
396 }
简单看一下抽象类的结构图:
说明一下:
这个抽象类中存在:抽象方法的声明,一些具体方法的实现,也内置了一些内部类:
private class Itr implements Iterator<E> {}
private class ListItr extends Itr implements ListIterator<E> {}
以上2两种迭代器丰富了AbstractList这个抽象类的迭代方式,以后继承这个抽象类的子类也可以重写会直接复用,为子类提供了多样化的功能。
一直在说:以上的接口或者抽象类只是在定义集合的规则,有些人就会有疑惑了,明明这个接口或者抽象类中也有一些实现了功能的方法啊。
其实对于一个集合来说,最重要的是什么?是如何把数据存进去,存在哪里,如何存放,如何取出来,如何存放到一个迭代器中(我们都知道是以链表的形式存放),那么从上面的接口或者抽象类中,我并没有发现:
(1)数据的存放的位置(数组,list集合中维护的是数组)。
(2)数据如何存放在迭代器中的链表。
以上这2中核心实现的代码,并不存在于上述的接口和抽象类中,所以我们接着往下看,继续去寻找答案!!!
6、看看接口:List<E>中定义了那些规则?
贴上JDK1.8中的源码:


1 package java.util;
2 import java.util.function.UnaryOperator;
3 public interface List<E> extends Collection<E> {
4 // Query Operations
5
6 /**
7 * Returns the number of elements in this list. If this list contains
8 * more than <tt>Integer.MAX_VALUE</tt> elements, returns
9 * <tt>Integer.MAX_VALUE</tt>.
10 *
11 * @return the number of elements in this list
12 */
13 int size();
14
15 /**
16 * Returns <tt>true</tt> if this list contains no elements.
17 *
18 * @return <tt>true</tt> if this list contains no elements
19 */
20 boolean isEmpty();
21
22 /**
23 * Returns <tt>true</tt> if this list contains the specified element.
24 * More formally, returns <tt>true</tt> if and only if this list contains
25 * at least one element <tt>e</tt> such that
26 * <tt>(o==null ? e==null : o.equals(e))</tt>.
27 *
28 * @param o element whose presence in this list is to be tested
29 * @return <tt>true</tt> if this list contains the specified element
30 * @throws ClassCastException if the type of the specified element
31 * is incompatible with this list
32 * (<a href="Collection.html#optional-restrictions">optional</a>)
33 * @throws NullPointerException if the specified element is null and this
34 * list does not permit null elements
35 * (<a href="Collection.html#optional-restrictions">optional</a>)
36 */
37 boolean contains(Object o);
38
39 /**
40 * Returns an iterator over the elements in this list in proper sequence.
41 *
42 * @return an iterator over the elements in this list in proper sequence
43 */
44 Iterator<E> iterator();
45
46 /**
47 * Returns an array containing all of the elements in this list in proper
48 * sequence (from first to last element).
49 *
50 * <p>The returned array will be "safe" in that no references to it are
51 * maintained by this list. (In other words, this method must
52 * allocate a new array even if this list is backed by an array).
53 * The caller is thus free to modify the returned array.
54 *
55 * <p>This method acts as bridge between array-based and collection-based
56 * APIs.
57 *
58 * @return an array containing all of the elements in this list in proper
59 * sequence
60 * @see Arrays#asList(Object[])
61 */
62 Object[] toArray();
63
64 /**
65 * Returns an array containing all of the elements in this list in
66 * proper sequence (from first to last element); the runtime type of
67 * the returned array is that of the specified array. If the list fits
68 * in the specified array, it is returned therein. Otherwise, a new
69 * array is allocated with the runtime type of the specified array and
70 * the size of this list.
71 *
72 * <p>If the list fits in the specified array with room to spare (i.e.,
73 * the array has more elements than the list), the element in the array
74 * immediately following the end of the list is set to <tt>null</tt>.
75 * (This is useful in determining the length of the list <i>only</i> if
76 * the caller knows that the list does not contain any null elements.)
77 *
78 * <p>Like the {@link #toArray()} method, this method acts as bridge between
79 * array-based and collection-based APIs. Further, this method allows
80 * precise control over the runtime type of the output array, and may,
81 * under certain circumstances, be used to save allocation costs.
82 *
83 * <p>Suppose <tt>x</tt> is a list known to contain only strings.
84 * The following code can be used to dump the list into a newly
85 * allocated array of <tt>String</tt>:
86 *
87 * <pre>{@code
88 * String[] y = x.toArray(new String[0]);
89 * }</pre>
90 *
91 * Note that <tt>toArray(new Object[0])</tt> is identical in function to
92 * <tt>toArray()</tt>.
93 *
94 * @param a the array into which the elements of this list are to
95 * be stored, if it is big enough; otherwise, a new array of the
96 * same runtime type is allocated for this purpose.
97 * @return an array containing the elements of this list
98 * @throws ArrayStoreException if the runtime type of the specified array
99 * is not a supertype of the runtime type of every element in
100 * this list
101 * @throws NullPointerException if the specified array is null
102 */
103 <T> T[] toArray(T[] a);
104
105
106 // Modification Operations
107
108 /**
109 * Appends the specified element to the end of this list (optional
110 * operation).
111 *
112 * <p>Lists that support this operation may place limitations on what
113 * elements may be added to this list. In particular, some
114 * lists will refuse to add null elements, and others will impose
115 * restrictions on the type of elements that may be added. List
116 * classes should clearly specify in their documentation any restrictions
117 * on what elements may be added.
118 *
119 * @param e element to be appended to this list
120 * @return <tt>true</tt> (as specified by {@link Collection#add})
121 * @throws UnsupportedOperationException if the <tt>add</tt> operation
122 * is not supported by this list
123 * @throws ClassCastException if the class of the specified element
124 * prevents it from being added to this list
125 * @throws NullPointerException if the specified element is null and this
126 * list does not permit null elements
127 * @throws IllegalArgumentException if some property of this element
128 * prevents it from being added to this list
129 */
130 boolean add(E e);
131
132 /**
133 * Removes the first occurrence of the specified element from this list,
134 * if it is present (optional operation). If this list does not contain
135 * the element, it is unchanged. More formally, removes the element with
136 * the lowest index <tt>i</tt> such that
137 * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>
138 * (if such an element exists). Returns <tt>true</tt> if this list
139 * contained the specified element (or equivalently, if this list changed
140 * as a result of the call).
141 *
142 * @param o element to be removed from this list, if present
143 * @return <tt>true</tt> if this list contained the specified element
144 * @throws ClassCastException if the type of the specified element
145 * is incompatible with this list
146 * (<a href="Collection.html#optional-restrictions">optional</a>)
147 * @throws NullPointerException if the specified element is null and this
148 * list does not permit null elements
149 * (<a href="Collection.html#optional-restrictions">optional</a>)
150 * @throws UnsupportedOperationException if the <tt>remove</tt> operation
151 * is not supported by this list
152 */
153 boolean remove(Object o);
154
155
156 // Bulk Modification Operations
157
158 /**
159 * Returns <tt>true</tt> if this list contains all of the elements of the
160 * specified collection.
161 *
162 * @param c collection to be checked for containment in this list
163 * @return <tt>true</tt> if this list contains all of the elements of the
164 * specified collection
165 * @throws ClassCastException if the types of one or more elements
166 * in the specified collection are incompatible with this
167 * list
168 * (<a href="Collection.html#optional-restrictions">optional</a>)
169 * @throws NullPointerException if the specified collection contains one
170 * or more null elements and this list does not permit null
171 * elements
172 * (<a href="Collection.html#optional-restrictions">optional</a>),
173 * or if the specified collection is null
174 * @see #contains(Object)
175 */
176 boolean containsAll(Collection<?> c);
177
178 /**
179 * Appends all of the elements in the specified collection to the end of
180 * this list, in the order that they are returned by the specified
181 * collection's iterator (optional operation). The behavior of this
182 * operation is undefined if the specified collection is modified while
183 * the operation is in progress. (Note that this will occur if the
184 * specified collection is this list, and it's nonempty.)
185 *
186 * @param c collection containing elements to be added to this list
187 * @return <tt>true</tt> if this list changed as a result of the call
188 * @throws UnsupportedOperationException if the <tt>addAll</tt> operation
189 * is not supported by this list
190 * @throws ClassCastException if the class of an element of the specified
191 * collection prevents it from being added to this list
192 * @throws NullPointerException if the specified collection contains one
193 * or more null elements and this list does not permit null
194 * elements, or if the specified collection is null
195 * @throws IllegalArgumentException if some property of an element of the
196 * specified collection prevents it from being added to this list
197 * @see #add(Object)
198 */
199 boolean addAll(Collection<? extends E> c);
200
201 /**
202 * Inserts all of the elements in the specified collection into this
203 * list at the specified position (optional operation). Shifts the
204 * element currently at that position (if any) and any subsequent
205 * elements to the right (increases their indices). The new elements
206 * will appear in this list in the order that they are returned by the
207 * specified collection's iterator. The behavior of this operation is
208 * undefined if the specified collection is modified while the
209 * operation is in progress. (Note that this will occur if the specified
210 * collection is this list, and it's nonempty.)
211 *
212 * @param index index at which to insert the first element from the
213 * specified collection
214 * @param c collection containing elements to be added to this list
215 * @return <tt>true</tt> if this list changed as a result of the call
216 * @throws UnsupportedOperationException if the <tt>addAll</tt> operation
217 * is not supported by this list
218 * @throws ClassCastException if the class of an element of the specified
219 * collection prevents it from being added to this list
220 * @throws NullPointerException if the specified collection contains one
221 * or more null elements and this list does not permit null
222 * elements, or if the specified collection is null
223 * @throws IllegalArgumentException if some property of an element of the
224 * specified collection prevents it from being added to this list
225 * @throws IndexOutOfBoundsException if the index is out of range
226 * (<tt>index < 0 || index > size()</tt>)
227 */
228 boolean addAll(int index, Collection<? extends E> c);
229
230 /**
231 * Removes from this list all of its elements that are contained in the
232 * specified collection (optional operation).
233 *
234 * @param c collection containing elements to be removed from this list
235 * @return <tt>true</tt> if this list changed as a result of the call
236 * @throws UnsupportedOperationException if the <tt>removeAll</tt> operation
237 * is not supported by this list
238 * @throws ClassCastException if the class of an element of this list
239 * is incompatible with the specified collection
240 * (<a href="Collection.html#optional-restrictions">optional</a>)
241 * @throws NullPointerException if this list contains a null element and the
242 * specified collection does not permit null elements
243 * (<a href="Collection.html#optional-restrictions">optional</a>),
244 * or if the specified collection is null
245 * @see #remove(Object)
246 * @see #contains(Object)
247 */
248 boolean removeAll(Collection<?> c);
249
250 /**
251 * Retains only the elements in this list that are contained in the
252 * specified collection (optional operation). In other words, removes
253 * from this list all of its elements that are not contained in the
254 * specified collection.
255 *
256 * @param c collection containing elements to be retained in this list
257 * @return <tt>true</tt> if this list changed as a result of the call
258 * @throws UnsupportedOperationException if the <tt>retainAll</tt> operation
259 * is not supported by this list
260 * @throws ClassCastException if the class of an element of this list
261 * is incompatible with the specified collection
262 * (<a href="Collection.html#optional-restrictions">optional</a>)
263 * @throws NullPointerException if this list contains a null element and the
264 * specified collection does not permit null elements
265 * (<a href="Collection.html#optional-restrictions">optional</a>),
266 * or if the specified collection is null
267 * @see #remove(Object)
268 * @see #contains(Object)
269 */
270 boolean retainAll(Collection<?> c);
271
272 /**
273 * Replaces each element of this list with the result of applying the
274 * operator to that element. Errors or runtime exceptions thrown by
275 * the operator are relayed to the caller.
276 *
277 * @implSpec
278 * The default implementation is equivalent to, for this {@code list}:
279 * <pre>{@code
280 * final ListIterator<E> li = list.listIterator();
281 * while (li.hasNext()) {
282 * li.set(operator.apply(li.next()));
283 * }
284 * }</pre>
285 *
286 * If the list's list-iterator does not support the {@code set} operation
287 * then an {@code UnsupportedOperationException} will be thrown when
288 * replacing the first element.
289 *
290 * @param operator the operator to apply to each element
291 * @throws UnsupportedOperationException if this list is unmodifiable.
292 * Implementations may throw this exception if an element
293 * cannot be replaced or if, in general, modification is not
294 * supported
295 * @throws NullPointerException if the specified operator is null or
296 * if the operator result is a null value and this list does
297 * not permit null elements
298 * (<a href="Collection.html#optional-restrictions">optional</a>)
299 * @since 1.8
300 */
301 default void replaceAll(UnaryOperator<E> operator) {
302 Objects.requireNonNull(operator);
303 final ListIterator<E> li = this.listIterator();
304 while (li.hasNext()) {
305 li.set(operator.apply(li.next()));
306 }
307 }
308
309 /**
310 * Sorts this list according to the order induced by the specified
311 * {@link Comparator}.
312 *
313 * <p>All elements in this list must be <i>mutually comparable</i> using the
314 * specified comparator (that is, {@code c.compare(e1, e2)} must not throw
315 * a {@code ClassCastException} for any elements {@code e1} and {@code e2}
316 * in the list).
317 *
318 * <p>If the specified comparator is {@code null} then all elements in this
319 * list must implement the {@link Comparable} interface and the elements'
320 * {@linkplain Comparable natural ordering} should be used.
321 *
322 * <p>This list must be modifiable, but need not be resizable.
323 *
324 * @implSpec
325 * The default implementation obtains an array containing all elements in
326 * this list, sorts the array, and iterates over this list resetting each
327 * element from the corresponding position in the array. (This avoids the
328 * n<sup>2</sup> log(n) performance that would result from attempting
329 * to sort a linked list in place.)
330 *
331 * @implNote
332 * This implementation is a stable, adaptive, iterative mergesort that
333 * requires far fewer than n lg(n) comparisons when the input array is
334 * partially sorted, while offering the performance of a traditional
335 * mergesort when the input array is randomly ordered. If the input array
336 * is nearly sorted, the implementation requires approximately n
337 * comparisons. Temporary storage requirements vary from a small constant
338 * for nearly sorted input arrays to n/2 object references for randomly
339 * ordered input arrays.
340 *
341 * <p>The implementation takes equal advantage of ascending and
342 * descending order in its input array, and can take advantage of
343 * ascending and descending order in different parts of the same
344 * input array. It is well-suited to merging two or more sorted arrays:
345 * simply concatenate the arrays and sort the resulting array.
346 *
347 * <p>The implementation was adapted from Tim Peters's list sort for Python
348 * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt">
349 * TimSort</a>). It uses techniques from Peter McIlroy's "Optimistic
350 * Sorting and Information Theoretic Complexity", in Proceedings of the
351 * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474,
352 * January 1993.
353 *
354 * @param c the {@code Comparator} used to compare list elements.
355 * A {@code null} value indicates that the elements'
356 * {@linkplain Comparable natural ordering} should be used
357 * @throws ClassCastException if the list contains elements that are not
358 * <i>mutually comparable</i> using the specified comparator
359 * @throws UnsupportedOperationException if the list's list-iterator does
360 * not support the {@code set} operation
361 * @throws IllegalArgumentException
362 * (<a href="Collection.html#optional-restrictions">optional</a>)
363 * if the comparator is found to violate the {@link Comparator}
364 * contract
365 * @since 1.8
366 */
367 @SuppressWarnings({"unchecked", "rawtypes"})
368 default void sort(Comparator<? super E> c) {
369 Object[] a = this.toArray();
370 Arrays.sort(a, (Comparator) c);
371 ListIterator<E> i = this.listIterator();
372 for (Object e : a) {
373 i.next();
374 i.set((E) e);
375 }
376 }
377
378 /**
379 * Removes all of the elements from this list (optional operation).
380 * The list will be empty after this call returns.
381 *
382 * @throws UnsupportedOperationException if the <tt>clear</tt> operation
383 * is not supported by this list
384 */
385 void clear();
386
387
388 // Comparison and hashing
389
390 /**
391 * Compares the specified object with this list for equality. Returns
392 * <tt>true</tt> if and only if the specified object is also a list, both
393 * lists have the same size, and all corresponding pairs of elements in
394 * the two lists are <i>equal</i>. (Two elements <tt>e1</tt> and
395 * <tt>e2</tt> are <i>equal</i> if <tt>(e1==null ? e2==null :
396 * e1.equals(e2))</tt>.) In other words, two lists are defined to be
397 * equal if they contain the same elements in the same order. This
398 * definition ensures that the equals method works properly across
399 * different implementations of the <tt>List</tt> interface.
400 *
401 * @param o the object to be compared for equality with this list
402 * @return <tt>true</tt> if the specified object is equal to this list
403 */
404 boolean equals(Object o);
405
406 /**
407 * Returns the hash code value for this list. The hash code of a list
408 * is defined to be the result of the following calculation:
409 * <pre>{@code
410 * int hashCode = 1;
411 * for (E e : list)
412 * hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
413 * }</pre>
414 * This ensures that <tt>list1.equals(list2)</tt> implies that
415 * <tt>list1.hashCode()==list2.hashCode()</tt> for any two lists,
416 * <tt>list1</tt> and <tt>list2</tt>, as required by the general
417 * contract of {@link Object#hashCode}.
418 *
419 * @return the hash code value for this list
420 * @see Object#equals(Object)
421 * @see #equals(Object)
422 */
423 int hashCode();
424
425
426 // Positional Access Operations
427
428 /**
429 * Returns the element at the specified position in this list.
430 *
431 * @param index index of the element to return
432 * @return the element at the specified position in this list
433 * @throws IndexOutOfBoundsException if the index is out of range
434 * (<tt>index < 0 || index >= size()</tt>)
435 */
436 E get(int index);
437
438 /**
439 * Replaces the element at the specified position in this list with the
440 * specified element (optional operation).
441 *
442 * @param index index of the element to replace
443 * @param element element to be stored at the specified position
444 * @return the element previously at the specified position
445 * @throws UnsupportedOperationException if the <tt>set</tt> operation
446 * is not supported by this list
447 * @throws ClassCastException if the class of the specified element
448 * prevents it from being added to this list
449 * @throws NullPointerException if the specified element is null and
450 * this list does not permit null elements
451 * @throws IllegalArgumentException if some property of the specified
452 * element prevents it from being added to this list
453 * @throws IndexOutOfBoundsException if the index is out of range
454 * (<tt>index < 0 || index >= size()</tt>)
455 */
456 E set(int index, E element);
457
458 /**
459 * Inserts the specified element at the specified position in this list
460 * (optional operation). Shifts the element currently at that position
461 * (if any) and any subsequent elements to the right (adds one to their
462 * indices).
463 *
464 * @param index index at which the specified element is to be inserted
465 * @param element element to be inserted
466 * @throws UnsupportedOperationException if the <tt>add</tt> operation
467 * is not supported by this list
468 * @throws ClassCastException if the class of the specified element
469 * prevents it from being added to this list
470 * @throws NullPointerException if the specified element is null and
471 * this list does not permit null elements
472 * @throws IllegalArgumentException if some property of the specified
473 * element prevents it from being added to this list
474 * @throws IndexOutOfBoundsException if the index is out of range
475 * (<tt>index < 0 || index > size()</tt>)
476 */
477 void add(int index, E element);
478
479 /**
480 * Removes the element at the specified position in this list (optional
481 * operation). Shifts any subsequent elements to the left (subtracts one
482 * from their indices). Returns the element that was removed from the
483 * list.
484 *
485 * @param index the index of the element to be removed
486 * @return the element previously at the specified position
487 * @throws UnsupportedOperationException if the <tt>remove</tt> operation
488 * is not supported by this list
489 * @throws IndexOutOfBoundsException if the index is out of range
490 * (<tt>index < 0 || index >= size()</tt>)
491 */
492 E remove(int index);
493
494
495 // Search Operations
496
497 /**
498 * Returns the index of the first occurrence of the specified element
499 * in this list, or -1 if this list does not contain the element.
500 * More formally, returns the lowest index <tt>i</tt> such that
501 * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
502 * or -1 if there is no such index.
503 *
504 * @param o element to search for
505 * @return the index of the first occurrence of the specified element in
506 * this list, or -1 if this list does not contain the element
507 * @throws ClassCastException if the type of the specified element
508 * is incompatible with this list
509 * (<a href="Collection.html#optional-restrictions">optional</a>)
510 * @throws NullPointerException if the specified element is null and this
511 * list does not permit null elements
512 * (<a href="Collection.html#optional-restrictions">optional</a>)
513 */
514 int indexOf(Object o);
515
516 /**
517 * Returns the index of the last occurrence of the specified element
518 * in this list, or -1 if this list does not contain the element.
519 * More formally, returns the highest index <tt>i</tt> such that
520 * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
521 * or -1 if there is no such index.
522 *
523 * @param o element to search for
524 * @return the index of the last occurrence of the specified element in
525 * this list, or -1 if this list does not contain the element
526 * @throws ClassCastException if the type of the specified element
527 * is incompatible with this list
528 * (<a href="Collection.html#optional-restrictions">optional</a>)
529 * @throws NullPointerException if the specified element is null and this
530 * list does not permit null elements
531 * (<a href="Collection.html#optional-restrictions">optional</a>)
532 */
533 int lastIndexOf(Object o);
534
535
536 // List Iterators
537
538 /**
539 * Returns a list iterator over the elements in this list (in proper
540 * sequence).
541 *
542 * @return a list iterator over the elements in this list (in proper
543 * sequence)
544 */
545 ListIterator<E> listIterator();
546
547 /**
548 * Returns a list iterator over the elements in this list (in proper
549 * sequence), starting at the specified position in the list.
550 * The specified index indicates the first element that would be
551 * returned by an initial call to {@link ListIterator#next next}.
552 * An initial call to {@link ListIterator#previous previous} would
553 * return the element with the specified index minus one.
554 *
555 * @param index index of the first element to be returned from the
556 * list iterator (by a call to {@link ListIterator#next next})
557 * @return a list iterator over the elements in this list (in proper
558 * sequence), starting at the specified position in the list
559 * @throws IndexOutOfBoundsException if the index is out of range
560 * ({@code index < 0 || index > size()})
561 */
562 ListIterator<E> listIterator(int index);
563
564 // View
565
566 /**
567 * Returns a view of the portion of this list between the specified
568 * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive. (If
569 * <tt>fromIndex</tt> and <tt>toIndex</tt> are equal, the returned list is
570 * empty.) The returned list is backed by this list, so non-structural
571 * changes in the returned list are reflected in this list, and vice-versa.
572 * The returned list supports all of the optional list operations supported
573 * by this list.<p>
574 *
575 * This method eliminates the need for explicit range operations (of
576 * the sort that commonly exist for arrays). Any operation that expects
577 * a list can be used as a range operation by passing a subList view
578 * instead of a whole list. For example, the following idiom
579 * removes a range of elements from a list:
580 * <pre>{@code
581 * list.subList(from, to).clear();
582 * }</pre>
583 * Similar idioms may be constructed for <tt>indexOf</tt> and
584 * <tt>lastIndexOf</tt>, and all of the algorithms in the
585 * <tt>Collections</tt> class can be applied to a subList.<p>
586 *
587 * The semantics of the list returned by this method become undefined if
588 * the backing list (i.e., this list) is <i>structurally modified</i> in
589 * any way other than via the returned list. (Structural modifications are
590 * those that change the size of this list, or otherwise perturb it in such
591 * a fashion that iterations in progress may yield incorrect results.)
592 *
593 * @param fromIndex low endpoint (inclusive) of the subList
594 * @param toIndex high endpoint (exclusive) of the subList
595 * @return a view of the specified range within this list
596 * @throws IndexOutOfBoundsException for an illegal endpoint index value
597 * (<tt>fromIndex < 0 || toIndex > size ||
598 * fromIndex > toIndex</tt>)
599 */
600 List<E> subList(int fromIndex, int toIndex);
601
602 /**
603 * Creates a {@link Spliterator} over the elements in this list.
604 *
605 * <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and
606 * {@link Spliterator#ORDERED}. Implementations should document the
607 * reporting of additional characteristic values.
608 *
609 * @implSpec
610 * The default implementation creates a
611 * <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
612 * from the list's {@code Iterator}. The spliterator inherits the
613 * <em>fail-fast</em> properties of the list's iterator.
614 *
615 * @implNote
616 * The created {@code Spliterator} additionally reports
617 * {@link Spliterator#SUBSIZED}.
618 *
619 * @return a {@code Spliterator} over the elements in this list
620 * @since 1.8
621 */
622 @Override
623 default Spliterator<E> spliterator() {
624 return Spliterators.spliterator(this, Spliterator.ORDERED);
625 }
626 }
简单看一下抽象类的结构图:
说明一下:
从源码和抽象类的结构图中,同样可以看到:
(1)List接口中没有说明集合数据是存放在哪里的?只是声明了一些集合操作的方法。、
(2)List接口中没有看到迭代器是如何获取集合数据并存放到链表中的:如下:
ListIterator<E> listIterator();
ListIterator<E> listIterator(int index);
所以想要探明究竟,就只能继续往下看,层层往下,直到ArrayList实现子类。
7、看看实现类:ArrayList<E>是如何实现集合功能的?
贴上JDK1.8中的源码:(内容有点多,会在下面捡重要的说明一下)


1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 *
5 *
6 *
7 *
8 *
9 *
10 *
11 *
12 *
13 *
14 *
15 *
16 *
17 *
18 *
19 *
20 *
21 *
22 *
23 *
24 */
25
26 package java.util;
27
28 import java.util.function.Consumer;
29 import java.util.function.Predicate;
30 import java.util.function.UnaryOperator;
31
32 /**
33 * Resizable-array implementation of the <tt>List</tt> interface. Implements
34 * all optional list operations, and permits all elements, including
35 * <tt>null</tt>. In addition to implementing the <tt>List</tt> interface,
36 * this class provides methods to manipulate the size of the array that is
37 * used internally to store the list. (This class is roughly equivalent to
38 * <tt>Vector</tt>, except that it is unsynchronized.)
39 *
40 * <p>The <tt>size</tt>, <tt>isEmpty</tt>, <tt>get</tt>, <tt>set</tt>,
41 * <tt>iterator</tt>, and <tt>listIterator</tt> operations run in constant
42 * time. The <tt>add</tt> operation runs in <i>amortized constant time</i>,
43 * that is, adding n elements requires O(n) time. All of the other operations
44 * run in linear time (roughly speaking). The constant factor is low compared
45 * to that for the <tt>LinkedList</tt> implementation.
46 *
47 * <p>Each <tt>ArrayList</tt> instance has a <i>capacity</i>. The capacity is
48 * the size of the array used to store the elements in the list. It is always
49 * at least as large as the list size. As elements are added to an ArrayList,
50 * its capacity grows automatically. The details of the growth policy are not
51 * specified beyond the fact that adding an element has constant amortized
52 * time cost.
53 *
54 * <p>An application can increase the capacity of an <tt>ArrayList</tt> instance
55 * before adding a large number of elements using the <tt>ensureCapacity</tt>
56 * operation. This may reduce the amount of incremental reallocation.
57 *
58 * <p><strong>Note that this implementation is not synchronized.</strong>
59 * If multiple threads access an <tt>ArrayList</tt> instance concurrently,
60 * and at least one of the threads modifies the list structurally, it
61 * <i>must</i> be synchronized externally. (A structural modification is
62 * any operation that adds or deletes one or more elements, or explicitly
63 * resizes the backing array; merely setting the value of an element is not
64 * a structural modification.) This is typically accomplished by
65 * synchronizing on some object that naturally encapsulates the list.
66 *
67 * If no such object exists, the list should be "wrapped" using the
68 * {@link Collections#synchronizedList Collections.synchronizedList}
69 * method. This is best done at creation time, to prevent accidental
70 * unsynchronized access to the list:<pre>
71 * List list = Collections.synchronizedList(new ArrayList(...));</pre>
72 *
73 * <p><a name="fail-fast">
74 * The iterators returned by this class's {@link #iterator() iterator} and
75 * {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>:</a>
76 * if the list is structurally modified at any time after the iterator is
77 * created, in any way except through the iterator's own
78 * {@link ListIterator#remove() remove} or
79 * {@link ListIterator#add(Object) add} methods, the iterator will throw a
80 * {@link ConcurrentModificationException}. Thus, in the face of
81 * concurrent modification, the iterator fails quickly and cleanly, rather
82 * than risking arbitrary, non-deterministic behavior at an undetermined
83 * time in the future.
84 *
85 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
86 * as it is, generally speaking, impossible to make any hard guarantees in the
87 * presence of unsynchronized concurrent modification. Fail-fast iterators
88 * throw {@code ConcurrentModificationException} on a best-effort basis.
89 * Therefore, it would be wrong to write a program that depended on this
90 * exception for its correctness: <i>the fail-fast behavior of iterators
91 * should be used only to detect bugs.</i>
92 *
93 * <p>This class is a member of the
94 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
95 * Java Collections Framework</a>.
96 *
97 * @author Josh Bloch
98 * @author Neal Gafter
99 * @see Collection
100 * @see List
101 * @see LinkedList
102 * @see Vector
103 * @since 1.2
104 */
105
106 public class ArrayList<E> extends AbstractList<E>
107 implements List<E>, RandomAccess, Cloneable, java.io.Serializable
108 {
109 private static final long serialVersionUID = 8683452581122892189L;
110
111 /**
112 * Default initial capacity.
113 */
114 private static final int DEFAULT_CAPACITY = 10;
115
116 /**
117 * Shared empty array instance used for empty instances.
118 */
119 private static final Object[] EMPTY_ELEMENTDATA = {};
120
121 /**
122 * Shared empty array instance used for default sized empty instances. We
123 * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
124 * first element is added.
125 */
126 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
127
128 /**
129 * The array buffer into which the elements of the ArrayList are stored.
130 * The capacity of the ArrayList is the length of this array buffer. Any
131 * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
132 * will be expanded to DEFAULT_CAPACITY when the first element is added.
133 */
134 transient Object[] elementData; // non-private to simplify nested class access
135
136 /**
137 * The size of the ArrayList (the number of elements it contains).
138 *
139 * @serial
140 */
141 private int size;
142
143 /**
144 * Constructs an empty list with the specified initial capacity.
145 *
146 * @param initialCapacity the initial capacity of the list
147 * @throws IllegalArgumentException if the specified initial capacity
148 * is negative
149 */
150 public ArrayList(int initialCapacity) {
151 if (initialCapacity > 0) {
152 this.elementData = new Object[initialCapacity];
153 } else if (initialCapacity == 0) {
154 this.elementData = EMPTY_ELEMENTDATA;
155 } else {
156 throw new IllegalArgumentException("Illegal Capacity: "+
157 initialCapacity);
158 }
159 }
160
161 /**
162 * Constructs an empty list with an initial capacity of ten.
163 */
164 public ArrayList() {
165 this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
166 }
167
168 /**
169 * Constructs a list containing the elements of the specified
170 * collection, in the order they are returned by the collection's
171 * iterator.
172 *
173 * @param c the collection whose elements are to be placed into this list
174 * @throws NullPointerException if the specified collection is null
175 */
176 public ArrayList(Collection<? extends E> c) {
177 elementData = c.toArray();
178 if ((size = elementData.length) != 0) {
179 // c.toArray might (incorrectly) not return Object[] (see 6260652)
180 if (elementData.getClass() != Object[].class)
181 elementData = Arrays.copyOf(elementData, size, Object[].class);
182 } else {
183 // replace with empty array.
184 this.elementData = EMPTY_ELEMENTDATA;
185 }
186 }
187
188 /**
189 * Trims the capacity of this <tt>ArrayList</tt> instance to be the
190 * list's current size. An application can use this operation to minimize
191 * the storage of an <tt>ArrayList</tt> instance.
192 */
193 public void trimToSize() {
194 modCount++;
195 if (size < elementData.length) {
196 elementData = (size == 0)
197 ? EMPTY_ELEMENTDATA
198 : Arrays.copyOf(elementData, size);
199 }
200 }
201
202 /**
203 * Increases the capacity of this <tt>ArrayList</tt> instance, if
204 * necessary, to ensure that it can hold at least the number of elements
205 * specified by the minimum capacity argument.
206 *
207 * @param minCapacity the desired minimum capacity
208 */
209 public void ensureCapacity(int minCapacity) {
210 int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
211 // any size if not default element table
212 ? 0
213 // larger than default for default empty table. It's already
214 // supposed to be at default size.
215 : DEFAULT_CAPACITY;
216
217 if (minCapacity > minExpand) {
218 ensureExplicitCapacity(minCapacity);
219 }
220 }
221
222 private void ensureCapacityInternal(int minCapacity) {
223 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
224 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
225 }
226
227 ensureExplicitCapacity(minCapacity);
228 }
229
230 private void ensureExplicitCapacity(int minCapacity) {
231 modCount++;
232
233 // overflow-conscious code
234 if (minCapacity - elementData.length > 0)
235 grow(minCapacity);
236 }
237
238 /**
239 * The maximum size of array to allocate.
240 * Some VMs reserve some header words in an array.
241 * Attempts to allocate larger arrays may result in
242 * OutOfMemoryError: Requested array size exceeds VM limit
243 */
244 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
245
246 /**
247 * Increases the capacity to ensure that it can hold at least the
248 * number of elements specified by the minimum capacity argument.
249 *
250 * @param minCapacity the desired minimum capacity
251 */
252 private void grow(int minCapacity) {
253 // overflow-conscious code
254 int oldCapacity = elementData.length;
255 int newCapacity = oldCapacity + (oldCapacity >> 1);
256 if (newCapacity - minCapacity < 0)
257 newCapacity = minCapacity;
258 if (newCapacity - MAX_ARRAY_SIZE > 0)
259 newCapacity = hugeCapacity(minCapacity);
260 // minCapacity is usually close to size, so this is a win:
261 elementData = Arrays.copyOf(elementData, newCapacity);
262 }
263
264 private static int hugeCapacity(int minCapacity) {
265 if (minCapacity < 0) // overflow
266 throw new OutOfMemoryError();
267 return (minCapacity > MAX_ARRAY_SIZE) ?
268 Integer.MAX_VALUE :
269 MAX_ARRAY_SIZE;
270 }
271
272 /**
273 * Returns the number of elements in this list.
274 *
275 * @return the number of elements in this list
276 */
277 public int size() {
278 return size;
279 }
280
281 /**
282 * Returns <tt>true</tt> if this list contains no elements.
283 *
284 * @return <tt>true</tt> if this list contains no elements
285 */
286 public boolean isEmpty() {
287 return size == 0;
288 }
289
290 /**
291 * Returns <tt>true</tt> if this list contains the specified element.
292 * More formally, returns <tt>true</tt> if and only if this list contains
293 * at least one element <tt>e</tt> such that
294 * <tt>(o==null ? e==null : o.equals(e))</tt>.
295 *
296 * @param o element whose presence in this list is to be tested
297 * @return <tt>true</tt> if this list contains the specified element
298 */
299 public boolean contains(Object o) {
300 return indexOf(o) >= 0;
301 }
302
303 /**
304 * Returns the index of the first occurrence of the specified element
305 * in this list, or -1 if this list does not contain the element.
306 * More formally, returns the lowest index <tt>i</tt> such that
307 * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
308 * or -1 if there is no such index.
309 */
310 public int indexOf(Object o) {
311 if (o == null) {
312 for (int i = 0; i < size; i++)
313 if (elementData[i]==null)
314 return i;
315 } else {
316 for (int i = 0; i < size; i++)
317 if (o.equals(elementData[i]))
318 return i;
319 }
320 return -1;
321 }
322
323 /**
324 * Returns the index of the last occurrence of the specified element
325 * in this list, or -1 if this list does not contain the element.
326 * More formally, returns the highest index <tt>i</tt> such that
327 * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
328 * or -1 if there is no such index.
329 */
330 public int lastIndexOf(Object o) {
331 if (o == null) {
332 for (int i = size-1; i >= 0; i--)
333 if (elementData[i]==null)
334 return i;
335 } else {
336 for (int i = size-1; i >= 0; i--)
337 if (o.equals(elementData[i]))
338 return i;
339 }
340 return -1;
341 }
342
343 /**
344 * Returns a shallow copy of this <tt>ArrayList</tt> instance. (The
345 * elements themselves are not copied.)
346 *
347 * @return a clone of this <tt>ArrayList</tt> instance
348 */
349 public Object clone() {
350 try {
351 ArrayList<?> v = (ArrayList<?>) super.clone();
352 v.elementData = Arrays.copyOf(elementData, size);
353 v.modCount = 0;
354 return v;
355 } catch (CloneNotSupportedException e) {
356 // this shouldn't happen, since we are Cloneable
357 throw new InternalError(e);
358 }
359 }
360
361 /**
362 * Returns an array containing all of the elements in this list
363 * in proper sequence (from first to last element).
364 *
365 * <p>The returned array will be "safe" in that no references to it are
366 * maintained by this list. (In other words, this method must allocate
367 * a new array). The caller is thus free to modify the returned array.
368 *
369 * <p>This method acts as bridge between array-based and collection-based
370 * APIs.
371 *
372 * @return an array containing all of the elements in this list in
373 * proper sequence
374 */
375 public Object[] toArray() {
376 return Arrays.copyOf(elementData, size);
377 }
378
379 /**
380 * Returns an array containing all of the elements in this list in proper
381 * sequence (from first to last element); the runtime type of the returned
382 * array is that of the specified array. If the list fits in the
383 * specified array, it is returned therein. Otherwise, a new array is
384 * allocated with the runtime type of the specified array and the size of
385 * this list.
386 *
387 * <p>If the list fits in the specified array with room to spare
388 * (i.e., the array has more elements than the list), the element in
389 * the array immediately following the end of the collection is set to
390 * <tt>null</tt>. (This is useful in determining the length of the
391 * list <i>only</i> if the caller knows that the list does not contain
392 * any null elements.)
393 *
394 * @param a the array into which the elements of the list are to
395 * be stored, if it is big enough; otherwise, a new array of the
396 * same runtime type is allocated for this purpose.
397 * @return an array containing the elements of the list
398 * @throws ArrayStoreException if the runtime type of the specified array
399 * is not a supertype of the runtime type of every element in
400 * this list
401 * @throws NullPointerException if the specified array is null
402 */
403 @SuppressWarnings("unchecked")
404 public <T> T[] toArray(T[] a) {
405 if (a.length < size)
406 // Make a new array of a's runtime type, but my contents:
407 return (T[]) Arrays.copyOf(elementData, size, a.getClass());
408 System.arraycopy(elementData, 0, a, 0, size);
409 if (a.length > size)
410 a[size] = null;
411 return a;
412 }
413
414 // Positional Access Operations
415
416 @SuppressWarnings("unchecked")
417 E elementData(int index) {
418 return (E) elementData[index];
419 }
420
421 /**
422 * Returns the element at the specified position in this list.
423 *
424 * @param index index of the element to return
425 * @return the element at the specified position in this list
426 * @throws IndexOutOfBoundsException {@inheritDoc}
427 */
428 public E get(int index) {
429 rangeCheck(index);
430
431 return elementData(index);
432 }
433
434 /**
435 * Replaces the element at the specified position in this list with
436 * the specified element.
437 *
438 * @param index index of the element to replace
439 * @param element element to be stored at the specified position
440 * @return the element previously at the specified position
441 * @throws IndexOutOfBoundsException {@inheritDoc}
442 */
443 public E set(int index, E element) {
444 rangeCheck(index);
445
446 E oldValue = elementData(index);
447 elementData[index] = element;
448 return oldValue;
449 }
450
451 /**
452 * Appends the specified element to the end of this list.
453 *
454 * @param e element to be appended to this list
455 * @return <tt>true</tt> (as specified by {@link Collection#add})
456 */
457 public boolean add(E e) {
458 ensureCapacityInternal(size + 1); // Increments modCount!!
459 elementData[size++] = e;
460 return true;
461 }
462
463 /**
464 * Inserts the specified element at the specified position in this
465 * list. Shifts the element currently at that position (if any) and
466 * any subsequent elements to the right (adds one to their indices).
467 *
468 * @param index index at which the specified element is to be inserted
469 * @param element element to be inserted
470 * @throws IndexOutOfBoundsException {@inheritDoc}
471 */
472 public void add(int index, E element) {
473 rangeCheckForAdd(index);
474
475 ensureCapacityInternal(size + 1); // Increments modCount!!
476 System.arraycopy(elementData, index, elementData, index + 1,
477 size - index);
478 elementData[index] = element;
479 size++;
480 }
481
482 /**
483 * Removes the element at the specified position in this list.
484 * Shifts any subsequent elements to the left (subtracts one from their
485 * indices).
486 *
487 * @param index the index of the element to be removed
488 * @return the element that was removed from the list
489 * @throws IndexOutOfBoundsException {@inheritDoc}
490 */
491 public E remove(int index) {
492 rangeCheck(index);
493
494 modCount++;
495 E oldValue = elementData(index);
496
497 int numMoved = size - index - 1;
498 if (numMoved > 0)
499 System.arraycopy(elementData, index+1, elementData, index,
500 numMoved);
501 elementData[--size] = null; // clear to let GC do its work
502
503 return oldValue;
504 }
505
506 /**
507 * Removes the first occurrence of the specified element from this list,
508 * if it is present. If the list does not contain the element, it is
509 * unchanged. More formally, removes the element with the lowest index
510 * <tt>i</tt> such that
511 * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>
512 * (if such an element exists). Returns <tt>true</tt> if this list
513 * contained the specified element (or equivalently, if this list
514 * changed as a result of the call).
515 *
516 * @param o element to be removed from this list, if present
517 * @return <tt>true</tt> if this list contained the specified element
518 */
519 public boolean remove(Object o) {
520 if (o == null) {
521 for (int index = 0; index < size; index++)
522 if (elementData[index] == null) {
523 fastRemove(index);
524 return true;
525 }
526 } else {
527 for (int index = 0; index < size; index++)
528 if (o.equals(elementData[index])) {
529 fastRemove(index);
530 return true;
531 }
532 }
533 return false;
534 }
535
536 /*
537 * Private remove method that skips bounds checking and does not
538 * return the value removed.
539 */
540 private void fastRemove(int index) {
541 modCount++;
542 int numMoved = size - index - 1;
543 if (numMoved > 0)
544 System.arraycopy(elementData, index+1, elementData, index,
545 numMoved);
546 elementData[--size] = null; // clear to let GC do its work
547 }
548
549 /**
550 * Removes all of the elements from this list. The list will
551 * be empty after this call returns.
552 */
553 public void clear() {
554 modCount++;
555
556 // clear to let GC do its work
557 for (int i = 0; i < size; i++)
558 elementData[i] = null;
559
560 size = 0;
561 }
562
563 /**
564 * Appends all of the elements in the specified collection to the end of
565 * this list, in the order that they are returned by the
566 * specified collection's Iterator. The behavior of this operation is
567 * undefined if the specified collection is modified while the operation
568 * is in progress. (This implies that the behavior of this call is
569 * undefined if the specified collection is this list, and this
570 * list is nonempty.)
571 *
572 * @param c collection containing elements to be added to this list
573 * @return <tt>true</tt> if this list changed as a result of the call
574 * @throws NullPointerException if the specified collection is null
575 */
576 public boolean addAll(Collection<? extends E> c) {
577 Object[] a = c.toArray();
578 int numNew = a.length;
579 ensureCapacityInternal(size + numNew); // Increments modCount
580 System.arraycopy(a, 0, elementData, size, numNew);
581 size += numNew;
582 return numNew != 0;
583 }
584
585 /**
586 * Inserts all of the elements in the specified collection into this
587 * list, starting at the specified position. Shifts the element
588 * currently at that position (if any) and any subsequent elements to
589 * the right (increases their indices). The new elements will appear
590 * in the list in the order that they are returned by the
591 * specified collection's iterator.
592 *
593 * @param index index at which to insert the first element from the
594 * specified collection
595 * @param c collection containing elements to be added to this list
596 * @return <tt>true</tt> if this list changed as a result of the call
597 * @throws IndexOutOfBoundsException {@inheritDoc}
598 * @throws NullPointerException if the specified collection is null
599 */
600 public boolean addAll(int index, Collection<? extends E> c) {
601 rangeCheckForAdd(index);
602
603 Object[] a = c.toArray();
604 int numNew = a.length;
605 ensureCapacityInternal(size + numNew); // Increments modCount
606
607 int numMoved = size - index;
608 if (numMoved > 0)
609 System.arraycopy(elementData, index, elementData, index + numNew,
610 numMoved);
611
612 System.arraycopy(a, 0, elementData, index, numNew);
613 size += numNew;
614 return numNew != 0;
615 }
616
617 /**
618 * Removes from this list all of the elements whose index is between
619 * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
620 * Shifts any succeeding elements to the left (reduces their index).
621 * This call shortens the list by {@code (toIndex - fromIndex)} elements.
622 * (If {@code toIndex==fromIndex}, this operation has no effect.)
623 *
624 * @throws IndexOutOfBoundsException if {@code fromIndex} or
625 * {@code toIndex} is out of range
626 * ({@code fromIndex < 0 ||
627 * fromIndex >= size() ||
628 * toIndex > size() ||
629 * toIndex < fromIndex})
630 */
631 protected void removeRange(int fromIndex, int toIndex) {
632 modCount++;
633 int numMoved = size - toIndex;
634 System.arraycopy(elementData, toIndex, elementData, fromIndex,
635 numMoved);
636
637 // clear to let GC do its work
638 int newSize = size - (toIndex-fromIndex);
639 for (int i = newSize; i < size; i++) {
640 elementData[i] = null;
641 }
642 size = newSize;
643 }
644
645 /**
646 * Checks if the given index is in range. If not, throws an appropriate
647 * runtime exception. This method does *not* check if the index is
648 * negative: It is always used immediately prior to an array access,
649 * which throws an ArrayIndexOutOfBoundsException if index is negative.
650 */
651 private void rangeCheck(int index) {
652 if (index >= size)
653 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
654 }
655
656 /**
657 * A version of rangeCheck used by add and addAll.
658 */
659 private void rangeCheckForAdd(int index) {
660 if (index > size || index < 0)
661 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
662 }
663
664 /**
665 * Constructs an IndexOutOfBoundsException detail message.
666 * Of the many possible refactorings of the error handling code,
667 * this "outlining" performs best with both server and client VMs.
668 */
669 private String outOfBoundsMsg(int index) {
670 return "Index: "+index+", Size: "+size;
671 }
672
673 /**
674 * Removes from this list all of its elements that are contained in the
675 * specified collection.
676 *
677 * @param c collection containing elements to be removed from this list
678 * @return {@code true} if this list changed as a result of the call
679 * @throws ClassCastException if the class of an element of this list
680 * is incompatible with the specified collection
681 * (<a href="Collection.html#optional-restrictions">optional</a>)
682 * @throws NullPointerException if this list contains a null element and the
683 * specified collection does not permit null elements
684 * (<a href="Collection.html#optional-restrictions">optional</a>),
685 * or if the specified collection is null
686 * @see Collection#contains(Object)
687 */
688 public boolean removeAll(Collection<?> c) {
689 Objects.requireNonNull(c);
690 return batchRemove(c, false);
691 }
692
693 /**
694 * Retains only the elements in this list that are contained in the
695 * specified collection. In other words, removes from this list all
696 * of its elements that are not contained in the specified collection.
697 *
698 * @param c collection containing elements to be retained in this list
699 * @return {@code true} if this list changed as a result of the call
700 * @throws ClassCastException if the class of an element of this list
701 * is incompatible with the specified collection
702 * (<a href="Collection.html#optional-restrictions">optional</a>)
703 * @throws NullPointerException if this list contains a null element and the
704 * specified collection does not permit null elements
705 * (<a href="Collection.html#optional-restrictions">optional</a>),
706 * or if the specified collection is null
707 * @see Collection#contains(Object)
708 */
709 public boolean retainAll(Collection<?> c) {
710 Objects.requireNonNull(c);
711 return batchRemove(c, true);
712 }
713
714 private boolean batchRemove(Collection<?> c, boolean complement) {
715 final Object[] elementData = this.elementData;
716 int r = 0, w = 0;
717 boolean modified = false;
718 try {
719 for (; r < size; r++)
720 if (c.contains(elementData[r]) == complement)
721 elementData[w++] = elementData[r];
722 } finally {
723 // Preserve behavioral compatibility with AbstractCollection,
724 // even if c.contains() throws.
725 if (r != size) {
726 System.arraycopy(elementData, r,
727 elementData, w,
728 size - r);
729 w += size - r;
730 }
731 if (w != size) {
732 // clear to let GC do its work
733 for (int i = w; i < size; i++)
734 elementData[i] = null;
735 modCount += size - w;
736 size = w;
737 modified = true;
738 }
739 }
740 return modified;
741 }
742
743 /**
744 * Save the state of the <tt>ArrayList</tt> instance to a stream (that
745 * is, serialize it).
746 *
747 * @serialData The length of the array backing the <tt>ArrayList</tt>
748 * instance is emitted (int), followed by all of its elements
749 * (each an <tt>Object</tt>) in the proper order.
750 */
751 private void writeObject(java.io.ObjectOutputStream s)
752 throws java.io.IOException{
753 // Write out element count, and any hidden stuff
754 int expectedModCount = modCount;
755 s.defaultWriteObject();
756
757 // Write out size as capacity for behavioural compatibility with clone()
758 s.writeInt(size);
759
760 // Write out all elements in the proper order.
761 for (int i=0; i<size; i++) {
762 s.writeObject(elementData[i]);
763 }
764
765 if (modCount != expectedModCount) {
766 throw new ConcurrentModificationException();
767 }
768 }
769
770 /**
771 * Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,
772 * deserialize it).
773 */
774 private void readObject(java.io.ObjectInputStream s)
775 throws java.io.IOException, ClassNotFoundException {
776 elementData = EMPTY_ELEMENTDATA;
777
778 // Read in size, and any hidden stuff
779 s.defaultReadObject();
780
781 // Read in capacity
782 s.readInt(); // ignored
783
784 if (size > 0) {
785 // be like clone(), allocate array based upon size not capacity
786 ensureCapacityInternal(size);
787
788 Object[] a = elementData;
789 // Read in all elements in the proper order.
790 for (int i=0; i<size; i++) {
791 a[i] = s.readObject();
792 }
793 }
794 }
795
796 /**
797 * Returns a list iterator over the elements in this list (in proper
798 * sequence), starting at the specified position in the list.
799 * The specified index indicates the first element that would be
800 * returned by an initial call to {@link ListIterator#next next}.
801 * An initial call to {@link ListIterator#previous previous} would
802 * return the element with the specified index minus one.
803 *
804 * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
805 *
806 * @throws IndexOutOfBoundsException {@inheritDoc}
807 */
808 public ListIterator<E> listIterator(int index) {
809 if (index < 0 || index > size)
810 throw new IndexOutOfBoundsException("Index: "+index);
811 return new ListItr(index);
812 }
813
814 /**
815 * Returns a list iterator over the elements in this list (in proper
816 * sequence).
817 *
818 * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
819 *
820 * @see #listIterator(int)
821 */
822 public ListIterator<E> listIterator() {
823 return new ListItr(0);
824 }
825
826 /**
827 * Returns an iterator over the elements in this list in proper sequence.
828 *
829 * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
830 *
831 * @return an iterator over the elements in this list in proper sequence
832 */
833 public Iterator<E> iterator() {
834 return new Itr();
835 }
836
837 /**
838 * An optimized version of AbstractList.Itr
839 */
840 private class Itr implements Iterator<E> {
841 int cursor; // index of next element to return
842 int lastRet = -1; // index of last element returned; -1 if no such
843 int expectedModCount = modCount;
844
845 public boolean hasNext() {
846 return cursor != size;
847 }
848
849 @SuppressWarnings("unchecked")
850 public E next() {
851 checkForComodification();
852 int i = cursor;
853 if (i >= size)
854 throw new NoSuchElementException();
855 Object[] elementData = ArrayList.this.elementData;
856 if (i >= elementData.length)
857 throw new ConcurrentModificationException();
858 cursor = i + 1;
859 return (E) elementData[lastRet = i];
860 }
861
862 public void remove() {
863 if (lastRet < 0)
864 throw new IllegalStateException();
865 checkForComodification();
866
867 try {
868 ArrayList.this.remove(lastRet);
869 cursor = lastRet;
870 lastRet = -1;
871 expectedModCount = modCount;
872 } catch (IndexOutOfBoundsException ex) {
873 throw new ConcurrentModificationException();
874 }
875 }
876
877 @Override
878 @SuppressWarnings("unchecked")
879 public void forEachRemaining(Consumer<? super E> consumer) {
880 Objects.requireNonNull(consumer);
881 final int size = ArrayList.this.size;
882 int i = cursor;
883 if (i >= size) {
884 return;
885 }
886 final Object[] elementData = ArrayList.this.elementData;
887 if (i >= elementData.length) {
888 throw new ConcurrentModificationException();
889 }
890 while (i != size && modCount == expectedModCount) {
891 consumer.accept((E) elementData[i++]);
892 }
893 // update once at end of iteration to reduce heap write traffic
894 cursor = i;
895 lastRet = i - 1;
896 checkForComodification();
897 }
898
899 final void checkForComodification() {
900 if (modCount != expectedModCount)
901 throw new ConcurrentModificationException();
902 }
903 }
904
905 /**
906 * An optimized version of AbstractList.ListItr
907 */
908 private class ListItr extends Itr implements ListIterator<E> {
909 ListItr(int index) {
910 super();
911 cursor = index;
912 }
913
914 public boolean hasPrevious() {
915 return cursor != 0;
916 }
917
918 public int nextIndex() {
919 return cursor;
920 }
921
922 public int previousIndex() {
923 return cursor - 1;
924 }
925
926 @SuppressWarnings("unchecked")
927 public E previous() {
928 checkForComodification();
929 int i = cursor - 1;
930 if (i < 0)
931 throw new NoSuchElementException();
932 Object[] elementData = ArrayList.this.elementData;
933 if (i >= elementData.length)
934 throw new ConcurrentModificationException();
935 cursor = i;
936 return (E) elementData[lastRet = i];
937 }
938
939 public void set(E e) {
940 if (lastRet < 0)
941 throw new IllegalStateException();
942 checkForComodification();
943
944 try {
945 ArrayList.this.set(lastRet, e);
946 } catch (IndexOutOfBoundsException ex) {
947 throw new ConcurrentModificationException();
948 }
949 }
950
951 public void add(E e) {
952 checkForComodification();
953
954 try {
955 int i = cursor;
956 ArrayList.this.add(i, e);
957 cursor = i + 1;
958 lastRet = -1;
959 expectedModCount = modCount;
960 } catch (IndexOutOfBoundsException ex) {
961 throw new ConcurrentModificationException();
962 }
963 }
964 }
965
966 /**
967 * Returns a view of the portion of this list between the specified
968 * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. (If
969 * {@code fromIndex} and {@code toIndex} are equal, the returned list is
970 * empty.) The returned list is backed by this list, so non-structural
971 * changes in the returned list are reflected in this list, and vice-versa.
972 * The returned list supports all of the optional list operations.
973 *
974 * <p>This method eliminates the need for explicit range operations (of
975 * the sort that commonly exist for arrays). Any operation that expects
976 * a list can be used as a range operation by passing a subList view
977 * instead of a whole list. For example, the following idiom
978 * removes a range of elements from a list:
979 * <pre>
980 * list.subList(from, to).clear();
981 * </pre>
982 * Similar idioms may be constructed for {@link #indexOf(Object)} and
983 * {@link #lastIndexOf(Object)}, and all of the algorithms in the
984 * {@link Collections} class can be applied to a subList.
985 *
986 * <p>The semantics of the list returned by this method become undefined if
987 * the backing list (i.e., this list) is <i>structurally modified</i> in
988 * any way other than via the returned list. (Structural modifications are
989 * those that change the size of this list, or otherwise perturb it in such
990 * a fashion that iterations in progress may yield incorrect results.)
991 *
992 * @throws IndexOutOfBoundsException {@inheritDoc}
993 * @throws IllegalArgumentException {@inheritDoc}
994 */
995 public List<E> subList(int fromIndex, int toIndex) {
996 subListRangeCheck(fromIndex, toIndex, size);
997 return new SubList(this, 0, fromIndex, toIndex);
998 }
999
1000 static void subListRangeCheck(int fromIndex, int toIndex, int size) {
1001 if (fromIndex < 0)
1002 throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
1003 if (toIndex > size)
1004 throw new IndexOutOfBoundsException("toIndex = " + toIndex);
1005 if (fromIndex > toIndex)
1006 throw new IllegalArgumentException("fromIndex(" + fromIndex +
1007 ") > toIndex(" + toIndex + ")");
1008 }
1009
1010 private class SubList extends AbstractList<E> implements RandomAccess {
1011 private final AbstractList<E> parent;
1012 private final int parentOffset;
1013 private final int offset;
1014 int size;
1015
1016 SubList(AbstractList<E> parent,
1017 int offset, int fromIndex, int toIndex) {
1018 this.parent = parent;
1019 this.parentOffset = fromIndex;
1020 this.offset = offset + fromIndex;
1021 this.size = toIndex - fromIndex;
1022 this.modCount = ArrayList.this.modCount;
1023 }
1024
1025 public E set(int index, E e) {
1026 rangeCheck(index);
1027 checkForComodification();
1028 E oldValue = ArrayList.this.elementData(offset + index);
1029 ArrayList.this.elementData[offset + index] = e;
1030 return oldValue;
1031 }
1032
1033 public E get(int index) {
1034 rangeCheck(index);
1035 checkForComodification();
1036 return ArrayList.this.elementData(offset + index);
1037 }
1038
1039 public int size() {
1040 checkForComodification();
1041 return this.size;
1042 }
1043
1044 public void add(int index, E e) {
1045 rangeCheckForAdd(index);
1046 checkForComodification();
1047 parent.add(parentOffset + index, e);
1048 this.modCount = parent.modCount;
1049 this.size++;
1050 }
1051
1052 public E remove(int index) {
1053 rangeCheck(index);
1054 checkForComodification();
1055 E result = parent.remove(parentOffset + index);
1056 this.modCount = parent.modCount;
1057 this.size--;
1058 return result;
1059 }
1060
1061 protected void removeRange(int fromIndex, int toIndex) {
1062 checkForComodification();
1063 parent.removeRange(parentOffset + fromIndex,
1064 parentOffset + toIndex);
1065 this.modCount = parent.modCount;
1066 this.size -= toIndex - fromIndex;
1067 }
1068
1069 public boolean addAll(Collection<? extends E> c) {
1070 return addAll(this.size, c);
1071 }
1072
1073 public boolean addAll(int index, Collection<? extends E> c) {
1074 rangeCheckForAdd(index);
1075 int cSize = c.size();
1076 if (cSize==0)
1077 return false;
1078
1079 checkForComodification();
1080 parent.addAll(parentOffset + index, c);
1081 this.modCount = parent.modCount;
1082 this.size += cSize;
1083 return true;
1084 }
1085
1086 public Iterator<E> iterator() {
1087 return listIterator();
1088 }
1089
1090 public ListIterator<E> listIterator(final int index) {
1091 checkForComodification();
1092 rangeCheckForAdd(index);
1093 final int offset = this.offset;
1094
1095 return new ListIterator<E>() {
1096 int cursor = index;
1097 int lastRet = -1;
1098 int expectedModCount = ArrayList.this.modCount;
1099
1100 public boolean hasNext() {
1101 return cursor != SubList.this.size;
1102 }
1103
1104 @SuppressWarnings("unchecked")
1105 public E next() {
1106 checkForComodification();
1107 int i = cursor;
1108 if (i >= SubList.this.size)
1109 throw new NoSuchElementException();
1110 Object[] elementData = ArrayList.this.elementData;
1111 if (offset + i >= elementData.length)
1112 throw new ConcurrentModificationException();
1113 cursor = i + 1;
1114 return (E) elementData[offset + (lastRet = i)];
1115 }
1116
1117 public boolean hasPrevious() {
1118 return cursor != 0;
1119 }
1120
1121 @SuppressWarnings("unchecked")
1122 public E previous() {
1123 checkForComodification();
1124 int i = cursor - 1;
1125 if (i < 0)
1126 throw new NoSuchElementException();
1127 Object[] elementData = ArrayList.this.elementData;
1128 if (offset + i >= elementData.length)
1129 throw new ConcurrentModificationException();
1130 cursor = i;
1131 return (E) elementData[offset + (lastRet = i)];
1132 }
1133
1134 @SuppressWarnings("unchecked")
1135 public void forEachRemaining(Consumer<? super E> consumer) {
1136 Objects.requireNonNull(consumer);
1137 final int size = SubList.this.size;
1138 int i = cursor;
1139 if (i >= size) {
1140 return;
1141 }
1142 final Object[] elementData = ArrayList.this.elementData;
1143 if (offset + i >= elementData.length) {
1144 throw new ConcurrentModificationException();
1145 }
1146 while (i != size && modCount == expectedModCount) {
1147 consumer.accept((E) elementData[offset + (i++)]);
1148 }
1149 // update once at end of iteration to reduce heap write traffic
1150 lastRet = cursor = i;
1151 checkForComodification();
1152 }
1153
1154 public int nextIndex() {
1155 return cursor;
1156 }
1157
1158 public int previousIndex() {
1159 return cursor - 1;
1160 }
1161
1162 public void remove() {
1163 if (lastRet < 0)
1164 throw new IllegalStateException();
1165 checkForComodification();
1166
1167 try {
1168 SubList.this.remove(lastRet);
1169 cursor = lastRet;
1170 lastRet = -1;
1171 expectedModCount = ArrayList.this.modCount;
1172 } catch (IndexOutOfBoundsException ex) {
1173 throw new ConcurrentModificationException();
1174 }
1175 }
1176
1177 public void set(E e) {
1178 if (lastRet < 0)
1179 throw new IllegalStateException();
1180 checkForComodification();
1181
1182 try {
1183 ArrayList.this.set(offset + lastRet, e);
1184 } catch (IndexOutOfBoundsException ex) {
1185 throw new ConcurrentModificationException();
1186 }
1187 }
1188
1189 public void add(E e) {
1190 checkForComodification();
1191
1192 try {
1193 int i = cursor;
1194 SubList.this.add(i, e);
1195 cursor = i + 1;
1196 lastRet = -1;
1197 expectedModCount = ArrayList.this.modCount;
1198 } catch (IndexOutOfBoundsException ex) {
1199 throw new ConcurrentModificationException();
1200 }
1201 }
1202
1203 final void checkForComodification() {
1204 if (expectedModCount != ArrayList.this.modCount)
1205 throw new ConcurrentModificationException();
1206 }
1207 };
1208 }
1209
1210 public List<E> subList(int fromIndex, int toIndex) {
1211 subListRangeCheck(fromIndex, toIndex, size);
1212 return new SubList(this, offset, fromIndex, toIndex);
1213 }
1214
1215 private void rangeCheck(int index) {
1216 if (index < 0 || index >= this.size)
1217 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1218 }
1219
1220 private void rangeCheckForAdd(int index) {
1221 if (index < 0 || index > this.size)
1222 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1223 }
1224
1225 private String outOfBoundsMsg(int index) {
1226 return "Index: "+index+", Size: "+this.size;
1227 }
1228
1229 private void checkForComodification() {
1230 if (ArrayList.this.modCount != this.modCount)
1231 throw new ConcurrentModificationException();
1232 }
1233
1234 public Spliterator<E> spliterator() {
1235 checkForComodification();
1236 return new ArrayListSpliterator<E>(ArrayList.this, offset,
1237 offset + this.size, this.modCount);
1238 }
1239 }
1240
1241 @Override
1242 public void forEach(Consumer<? super E> action) {
1243 Objects.requireNonNull(action);
1244 final int expectedModCount = modCount;
1245 @SuppressWarnings("unchecked")
1246 final E[] elementData = (E[]) this.elementData;
1247 final int size = this.size;
1248 for (int i=0; modCount == expectedModCount && i < size; i++) {
1249 action.accept(elementData[i]);
1250 }
1251 if (modCount != expectedModCount) {
1252 throw new ConcurrentModificationException();
1253 }
1254 }
1255
1256 /**
1257 * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
1258 * and <em>fail-fast</em> {@link Spliterator} over the elements in this
1259 * list.
1260 *
1261 * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
1262 * {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}.
1263 * Overriding implementations should document the reporting of additional
1264 * characteristic values.
1265 *
1266 * @return a {@code Spliterator} over the elements in this list
1267 * @since 1.8
1268 */
1269 @Override
1270 public Spliterator<E> spliterator() {
1271 return new ArrayListSpliterator<>(this, 0, -1, 0);
1272 }
1273
1274 /** Index-based split-by-two, lazily initialized Spliterator */
1275 static final class ArrayListSpliterator<E> implements Spliterator<E> {
1276
1277 /*
1278 * If ArrayLists were immutable, or structurally immutable (no
1279 * adds, removes, etc), we could implement their spliterators
1280 * with Arrays.spliterator. Instead we detect as much
1281 * interference during traversal as practical without
1282 * sacrificing much performance. We rely primarily on
1283 * modCounts. These are not guaranteed to detect concurrency
1284 * violations, and are sometimes overly conservative about
1285 * within-thread interference, but detect enough problems to
1286 * be worthwhile in practice. To carry this out, we (1) lazily
1287 * initialize fence and expectedModCount until the latest
1288 * point that we need to commit to the state we are checking
1289 * against; thus improving precision. (This doesn't apply to
1290 * SubLists, that create spliterators with current non-lazy
1291 * values). (2) We perform only a single
1292 * ConcurrentModificationException check at the end of forEach
1293 * (the most performance-sensitive method). When using forEach
1294 * (as opposed to iterators), we can normally only detect
1295 * interference after actions, not before. Further
1296 * CME-triggering checks apply to all other possible
1297 * violations of assumptions for example null or too-small
1298 * elementData array given its size(), that could only have
1299 * occurred due to interference. This allows the inner loop
1300 * of forEach to run without any further checks, and
1301 * simplifies lambda-resolution. While this does entail a
1302 * number of checks, note that in the common case of
1303 * list.stream().forEach(a), no checks or other computation
1304 * occur anywhere other than inside forEach itself. The other
1305 * less-often-used methods cannot take advantage of most of
1306 * these streamlinings.
1307 */
1308
1309 private final ArrayList<E> list;
1310 private int index; // current index, modified on advance/split
1311 private int fence; // -1 until used; then one past last index
1312 private int expectedModCount; // initialized when fence set
1313
1314 /** Create new spliterator covering the given range */
1315 ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
1316 int expectedModCount) {
1317 this.list = list; // OK if null unless traversed
1318 this.index = origin;
1319 this.fence = fence;
1320 this.expectedModCount = expectedModCount;
1321 }
1322
1323 private int getFence() { // initialize fence to size on first use
1324 int hi; // (a specialized variant appears in method forEach)
1325 ArrayList<E> lst;
1326 if ((hi = fence) < 0) {
1327 if ((lst = list) == null)
1328 hi = fence = 0;
1329 else {
1330 expectedModCount = lst.modCount;
1331 hi = fence = lst.size;
1332 }
1333 }
1334 return hi;
1335 }
1336
1337 public ArrayListSpliterator<E> trySplit() {
1338 int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
1339 return (lo >= mid) ? null : // divide range in half unless too small
1340 new ArrayListSpliterator<E>(list, lo, index = mid,
1341 expectedModCount);
1342 }
1343
1344 public boolean tryAdvance(Consumer<? super E> action) {
1345 if (action == null)
1346 throw new NullPointerException();
1347 int hi = getFence(), i = index;
1348 if (i < hi) {
1349 index = i + 1;
1350 @SuppressWarnings("unchecked") E e = (E)list.elementData[i];
1351 action.accept(e);
1352 if (list.modCount != expectedModCount)
1353 throw new ConcurrentModificationException();
1354 return true;
1355 }
1356 return false;
1357 }
1358
1359 public void forEachRemaining(Consumer<? super E> action) {
1360 int i, hi, mc; // hoist accesses and checks from loop
1361 ArrayList<E> lst; Object[] a;
1362 if (action == null)
1363 throw new NullPointerException();
1364 if ((lst = list) != null && (a = lst.elementData) != null) {
1365 if ((hi = fence) < 0) {
1366 mc = lst.modCount;
1367 hi = lst.size;
1368 }
1369 else
1370 mc = expectedModCount;
1371 if ((i = index) >= 0 && (index = hi) <= a.length) {
1372 for (; i < hi; ++i) {
1373 @SuppressWarnings("unchecked") E e = (E) a[i];
1374 action.accept(e);
1375 }
1376 if (lst.modCount == mc)
1377 return;
1378 }
1379 }
1380 throw new ConcurrentModificationException();
1381 }
1382
1383 public long estimateSize() {
1384 return (long) (getFence() - index);
1385 }
1386
1387 public int characteristics() {
1388 return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
1389 }
1390 }
1391
1392 @Override
1393 public boolean removeIf(Predicate<? super E> filter) {
1394 Objects.requireNonNull(filter);
1395 // figure out which elements are to be removed
1396 // any exception thrown from the filter predicate at this stage
1397 // will leave the collection unmodified
1398 int removeCount = 0;
1399 final BitSet removeSet = new BitSet(size);
1400 final int expectedModCount = modCount;
1401 final int size = this.size;
1402 for (int i=0; modCount == expectedModCount && i < size; i++) {
1403 @SuppressWarnings("unchecked")
1404 final E element = (E) elementData[i];
1405 if (filter.test(element)) {
1406 removeSet.set(i);
1407 removeCount++;
1408 }
1409 }
1410 if (modCount != expectedModCount) {
1411 throw new ConcurrentModificationException();
1412 }
1413
1414 // shift surviving elements left over the spaces left by removed elements
1415 final boolean anyToRemove = removeCount > 0;
1416 if (anyToRemove) {
1417 final int newSize = size - removeCount;
1418 for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
1419 i = removeSet.nextClearBit(i);
1420 elementData[j] = elementData[i];
1421 }
1422 for (int k=newSize; k < size; k++) {
1423 elementData[k] = null; // Let gc do its work
1424 }
1425 this.size = newSize;
1426 if (modCount != expectedModCount) {
1427 throw new ConcurrentModificationException();
1428 }
1429 modCount++;
1430 }
1431
1432 return anyToRemove;
1433 }
1434
1435 @Override
1436 @SuppressWarnings("unchecked")
1437 public void replaceAll(UnaryOperator<E> operator) {
1438 Objects.requireNonNull(operator);
1439 final int expectedModCount = modCount;
1440 final int size = this.size;
1441 for (int i=0; modCount == expectedModCount && i < size; i++) {
1442 elementData[i] = operator.apply((E) elementData[i]);
1443 }
1444 if (modCount != expectedModCount) {
1445 throw new ConcurrentModificationException();
1446 }
1447 modCount++;
1448 }
1449
1450 @Override
1451 @SuppressWarnings("unchecked")
1452 public void sort(Comparator<? super E> c) {
1453 final int expectedModCount = modCount;
1454 Arrays.sort((E[]) elementData, 0, size, c);
1455 if (modCount != expectedModCount) {
1456 throw new ConcurrentModificationException();
1457 }
1458 modCount++;
1459 }
1460 }
贴上类的结构图:
内容太长,分2次截图。
直接看看里面有些什么吧!
(1)存放集合数据的数组!
private static final Object[] EMPTY_ELEMENTDATA = {};//用于空实例的共享空数组实例。
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//扩展数组
transient Object[] elementData;//存放数据的原始数组
(2)实例化集合对象
//【1】传入集合大小,初始化集合容量,不够时自动扩展
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
//【2】直接拿到集合实例,不固定集合大小
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//【3】用另外一个集合来实例化当前集合
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
this.elementData = EMPTY_ELEMENTDATA;
}
}
分析说明一下:
(1)如果采用【1】中方式拿到集合对象,那么当超过设置的初始容量的时候是如何扩容的呢?
看下面这个例子:
1 public static void main(String[] args) throws Exception {
2 List list=new ArrayList(2);
3 System.out.println("扩展前集合容量1:"+getCapacity(list));
4 list.add(1);
5 list.add(2);
6 System.out.println("扩展前集合容量2:"+getCapacity(list));
7 list.add(3);
8 list.add(4);
9 System.out.println("扩展后集合容量3:"+getCapacity(list));
10 list.add(5);
11 list.add(6);
12 System.out.println("扩展后集合容量4:"+getCapacity(list));
13 list.add(7);
14 list.add(8);
15 System.out.println("扩展后集合容量5:"+getCapacity(list));
16 list.add(9);
17 System.out.println("扩展后集合容量6:"+getCapacity(list));
18 list.add(10);
19 System.out.println("扩展后集合容量7:"+getCapacity(list));
20 for(Object o:list){
21 System.out.println(o);
22 }
23 System.out.println("扩展后集合容量8:"+getCapacity(list));
24 }
25 //反射拿到当前集合保存数据的数组的容量
26 static int getCapacity(List<?> l) throws Exception {
27 Field dataField = ArrayList.class.getDeclaredField("elementData");
28 dataField.setAccessible(true);
29 return ((Object[]) dataField.get(l)).length;
30 }
输出结果:
扩展前集合容量1:2
扩展前集合容量2:2
扩展后集合容量3:4
扩展后集合容量4:6
扩展后集合容量5:9
扩展后集合容量6:9
扩展后集合容量7:13
1
2
3
4
5
6
7
8
9
10
扩展后集合容量8:13
从结果上,可以知道,扩展容量并不是均匀扩展的(每次都递增相同的容量),而是发生着变化的,那么这种变化规则是怎么样的呢?
继续分析一下源码中是怎么定义的:
1 //将指定的元素追加到列表的末尾
2 public boolean add(E e) {
3 ensureCapacityInternal(size + 1); // 增量模式计数!!
4 elementData[size++] = e;
5 return true;
6 }
7 //确定内部容量的方法
8 private void ensureCapacityInternal(int minCapacity) {
9 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
10 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
11 }
12 ensureExplicitCapacity(minCapacity);
13 }
14 private void ensureExplicitCapacity(int minCapacity) {
15 modCount++;
16 //判断当前集合是否超多最大容量,即是否有容量溢出现象
17 if (minCapacity - elementData.length > 0)
18 grow(minCapacity);
19 }
20 //集合内部维护的是数组扩容
21 private void grow(int minCapacity) {
22 int oldCapacity = elementData.length;//拿到当前集合大小
23 int newCapacity = oldCapacity + (oldCapacity >> 1);//计算集合新的容量大小
24 if (newCapacity - minCapacity < 0)
25 newCapacity = minCapacity;
26 if (newCapacity - MAX_ARRAY_SIZE > 0)
27 newCapacity = hugeCapacity(minCapacity);
28 //复制旧集合数据到新的集合中(内部维护的数组扩容-产生新的数组)
29 elementData = Arrays.copyOf(elementData, newCapacity);
30 }
那么在详细看以下2行代码是如何计算增加的容量的吧:
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
简单说明一下:“>>”运算符
>>运算规则:按二进制形式把所有的数字向右移动对应巍峨位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1.
语法格式:
需要移位的数字 >> 移位的次数
例如11 >> 2,则是将数字11右移2位
计算过程:11的二进制形式为:0000 0000 0000 0000 0000 0000 0000 1011,然后把低位的最后两个数字移出,因为该数字是正数,所以在高位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 0010.转换为十进制是3.数学意义:右移一位相当于除2,右移n位相当于除以2的n次方。
举一个简答的例子:
1 public static void main(String[] args) throws Exception {
2 for(int i=0;i<=10;i++){
3 System.out.println("******当前i="+i+"***********");
4 System.out.println("递增数值:"+((i>>1)));
5 System.out.println("递增数后值:"+(i+(i>>1)));
6 }
7 }
运行结果:
******当前i=0***********
递增数值:0
递增数后值:0
******当前i=1***********
递增数值:0
递增数后值:1
******当前i=2***********
递增数值:1
递增数后值:3
******当前i=3***********
递增数值:1
递增数后值:4
******当前i=4***********
递增数值:2
递增数后值:6
******当前i=5***********
递增数值:2
递增数后值:7
******当前i=6***********
递增数值:3
递增数后值:9
******当前i=7***********
递增数值:3
递增数后值:10
******当前i=8***********
递增数值:4
递增数后值:12
******当前i=9***********
递增数值:4
递增数后值:13
******当前i=10***********
递增数值:5
递增数后值:15
分析可以知道:每次递增的数值为:源数值的一半,且向下取整得到的数值。
(3)如何添加数据待集合中
ArrayList实现类中提供了2种方法,供添加数据使用:
public boolean add(E e) {//【1】直接在集合末尾添加一个数据
ensureCapacityInternal(size + 1); // 判断数据是否会溢出
elementData[size++] = e;
return true;
}
public void add(int index, E element) {//【2】添加一个数据到集合的指定位置
rangeCheckForAdd(index);//检查位置是否合法
ensureCapacityInternal(size + 1); // 判断数据是否会溢出
System.arraycopy(elementData, index, elementData, index + 1,//System提供了一个静态方法arraycopy(),我们可以使用它来实现数组之间的复制
size - index);
elementData[index] = element;
size++;
}
方法【1】直接在集合末尾添加一个数据,上面已经给出了分析,这里就不在赘述了,那么来看一下方法【2】是怎么处理的!
(1)在指定位置添加一个数据,这个指定的位置,就需要检查是否合法:
rangeCheckForAdd(index);//检查位置是否合法
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
(2)然后就是判断,如果新增了这个元素,会不会导致整个数组的数据溢出,如果会导致溢出现象,则要扩容数组。
具体的方法上面已经给出分析:这里再放一遍代码
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);
}
(3)此时,位置索引值合法,数组也不会溢出了,就开始要实现如何插入。
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
上面这句代码:
System提供了一个静态方法arraycopy(),我们可以使用它来实现数组之间的复制。其函数原型是:
public static void (Object src,
int srcPos,
Object dest,
int destPos,
int length)
参数说明:
src:源数组; srcPos:源数组要复制的起始位置;
dest:目的数组; destPos:目的数组放置的起始位置; length:复制的长度。
注意:src and dest都必须是同类型或者可以进行转换类型的数组.
有趣的是这个函数可以实现自己到自己复制,比如:
int[] fun ={0,1,2,3,4,5,6};
System.arraycopy(fun,0,fun,3,3);
则结果为:{0,1,2,0,1,2,6};
实现过程是这样的,先生成一个长度为length的临时数组,将fun数组中srcPos
到srcPos+length-1之间的数据拷贝到临时数组中,再执行System.arraycopy(临时数组,0,fun,3,3).
(4)实现了,指定位置之后(包含指定位置)的数据,向后移动的功能后,开始在指定的位置插入数据了。并且数据长度+1
elementData[index] = element;
size++;
(4)如何从集合中删除一个数据
ArrayList实现类中提供了2种方法,供删除数据使用:
public E remove(int index) {//【1】删除指定位置的数据
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; //置空该位置的数据
return oldValue;
}
public boolean remove(Object o) {//【2】删除指定的数据
if (o == null) {//当前要删除的数据为null
for (int index = 0; index < size; index++)
if (elementData[index] == null) {//遍历数组容量,拿到要删除数据的位置索引值
fastRemove(index);//调用删除元素的方法
return true;
}
} else {//当前要删除的数据不为null
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {//遍历数组容量,拿到要删除数据的位置索引值
fastRemove(index);//调用删除元素的方法
return true;
}
}
return false;
}
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
}
private void rangeCheck(int index) {//判断当前位置的索引值是否合法
if (index >= size)//要删除的数据的位置不可超过数组容量,说明:如果过小的话,也会造成异常的发生
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
总结一下;
(1)具体如何删除集合数据,上面代码+说明已经很明显了,这里也不在赘述了。
有意思的是:
private void rangeCheck(int index) {//判断当前位置的索引值是否合法
if (index >= size)//要删除的数据的位置不可超过数组容量,说明:如果过小的话,也会造成异常的发生
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
在删除指定位置的数据的时候,对这个位置索引值做了合法性判断。但是只做了上限判断,下限判断 没有做。
(1)当索引值超过数组上限容量的时候,会抛出:throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
(2)当索引值低于数组下限容量值0的时候,如何处理呢?
public static void main(String[] args) throws Exception {
List alist=Arrays.asList(1,2,3,4,5,6,7,8,9,10);
alist.remove(-1);
}
运行结果:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:161)
at com.xfwl.test.Test4.main(Test4.java:17)
分析说明:
根据运行结果,发现的确会抛出异常,但是并不是在ArrayList这个实现子类中抛出的,而是在ArrayList继承的AbstractList父类中抛出的,ArrayList重写了父类的方法,虽然其中并没有抛出: java.lang.UnsupportedOperationException
但是查看了源码,就可以知道:父类抽象类:AbstractList的remove(int index)方法中,抛出了异常。
public E remove(int index) {
throw new UnsupportedOperationException();
}
还有一种现象:就是我们删除数据的位置超过数组上限值,也抛出:java.lang.UnsupportedOperationException
public static void main(String[] args) {
List alist=Arrays.asList(1,2,3,4,5,6,7,8,9,10);
alist.remove(100);
}
运行结果:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:161)
at com.xfwl.test.Test2.main(Test2.java:11)
分析说明:
可以看到,超过上限值,也会抛出父类方法中的异常。
总结一下:
首先ArrayList是子类,AbstractList是父类。
(1)当子类中因为超过上限,而抛出:throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); 但是合格异常并没有被处理,会继续往上抛,就会抛到父类中去。而父类AbstractList的实现接口List和继承AbstractCollection类中都没有:
public E remove(int index)这个方法,换句话说就是, public E remove(int index)这个方法在AbstractList这里就终止了,也就抛出了AbstractList中的这个异常。
(2)当子类中因为地域下限时,由于没有异常捕获或者抛出处理,所以同样会到父类中捕获抛出异常。
(5)集合中是如何把数据传递给迭代器中的链表的呢?
分析JDK1.8的源码,可以知道:ArrayList中提供了,三个获取迭代器的方法,2个内置的具有继承关系的迭代器类。
三个获取迭代器的方法:
1 public ListIterator<E> listIterator(int index) {//【1】获取数组指定位置(不是索引值)之后的数组数据存放入迭代器链表中
2 if (index < 0 || index > size)
3 throw new IndexOutOfBoundsException("Index: "+index);
4 return new ListItr(index);
5 }
6 public ListIterator<E> listIterator() {//【2】默认的方法。获取所有的数组数据放入迭代器链表中
7 return new ListItr(0);
8 }
9
10 public Iterator<E> iterator() {//【3】默认方法。获取所有的数组数据放入迭代器链表中
11 return new Itr();
12 }
13 //说明:【2】和【3】的区别是返回的类型不懂,Iterator是ListIterator的父类
2个内置的迭代器类:
private class Itr implements Iterator<E> {}
Itr类内部结构图:


1 private class Itr implements Iterator<E> {
2 int cursor; // index of next element to return
3 int lastRet = -1; // index of last element returned; -1 if no such
4 int expectedModCount = modCount;
5
6 public boolean hasNext() {
7 return cursor != size;
8 }
9
10 @SuppressWarnings("unchecked")
11 public E next() {
12 checkForComodification();
13 int i = cursor;
14 if (i >= size)
15 throw new NoSuchElementException();
16 Object[] elementData = ArrayList.this.elementData;
17 if (i >= elementData.length)
18 throw new ConcurrentModificationException();
19 cursor = i + 1;
20 return (E) elementData[lastRet = i];
21 }
22
23 public void remove() {
24 if (lastRet < 0)
25 throw new IllegalStateException();
26 checkForComodification();
27
28 try {
29 ArrayList.this.remove(lastRet);
30 cursor = lastRet;
31 lastRet = -1;
32 expectedModCount = modCount;
33 } catch (IndexOutOfBoundsException ex) {
34 throw new ConcurrentModificationException();
35 }
36 }
37
38 @Override
39 @SuppressWarnings("unchecked")
40 public void forEachRemaining(Consumer<? super E> consumer) {
41 Objects.requireNonNull(consumer);
42 final int size = ArrayList.this.size;
43 int i = cursor;
44 if (i >= size) {
45 return;
46 }
47 final Object[] elementData = ArrayList.this.elementData;
48 if (i >= elementData.length) {
49 throw new ConcurrentModificationException();
50 }
51 while (i != size && modCount == expectedModCount) {
52 consumer.accept((E) elementData[i++]);
53 }
54 // update once at end of iteration to reduce heap write traffic
55 cursor = i;
56 lastRet = i - 1;
57 checkForComodification();
58 }
59
60 final void checkForComodification() {
61 if (modCount != expectedModCount)
62 throw new ConcurrentModificationException();
63 }
64 }
private class ListItr extends Itr implements ListIterator<E> {}
ListItr类内部结构图:


1 private class ListItr extends Itr implements ListIterator<E> {
2 ListItr(int index) {
3 super();
4 cursor = index;
5 }
6
7 public boolean hasPrevious() {
8 return cursor != 0;
9 }
10
11 public int nextIndex() {
12 return cursor;
13 }
14
15 public int previousIndex() {
16 return cursor - 1;
17 }
18
19 @SuppressWarnings("unchecked")
20 public E previous() {
21 checkForComodification();
22 int i = cursor - 1;
23 if (i < 0)
24 throw new NoSuchElementException();
25 Object[] elementData = ArrayList.this.elementData;
26 if (i >= elementData.length)
27 throw new ConcurrentModificationException();
28 cursor = i;
29 return (E) elementData[lastRet = i];
30 }
31
32 public void set(E e) {
33 if (lastRet < 0)
34 throw new IllegalStateException();
35 checkForComodification();
36
37 try {
38 ArrayList.this.set(lastRet, e);
39 } catch (IndexOutOfBoundsException ex) {
40 throw new ConcurrentModificationException();
41 }
42 }
43
44 public void add(E e) {
45 checkForComodification();
46
47 try {
48 int i = cursor;
49 ArrayList.this.add(i, e);
50 cursor = i + 1;
51 lastRet = -1;
52 expectedModCount = modCount;
53 } catch (IndexOutOfBoundsException ex) {
54 throw new ConcurrentModificationException();
55 }
56 }
57 }
从代码中,我们可以看到,这两种迭代器,从根本上来说都是使用实现了 Iterator接口来存储数据,定位数据,移动数据。
关于链表的数据结构,以后会在算法章节做另做模拟、测试和分析。
好了,此篇到此结束了!
来源:oschina
链接:https://my.oschina.net/u/4384021/blog/3987363