ArrayList其实就那么一回事儿之源码浅析
程序员文章站
2024-02-29 18:05:40
...
ArrayList 算是常用的集合之一了,不知作为javaner的你有没在百忙之中抽出一点时间看看ArrayList的源码呢。 如果看了,你会觉得其实ArrayList其实就那么一回事儿,对吧,下面就看看ArrayList的部分源码吧。
1 public class ArrayList<E> extends AbstractList<E>
2 implements List<E>, RandomAccess, Cloneable, java.io.Serializable
3 {
4 private static final long serialVersionUID = 8683452581122892189L;
5
6 //设置arrayList默认容量
7 private static final int DEFAULT_CAPACITY = 10;
8
9 //空数组,当调用无参数构造函数的时候默认给个空数组
10 private static final Object[] EMPTY_ELEMENTDATA = {};
11
12 //这才是真正保存数据的数组
13 private transient Object[] elementData;
14
15 //arrayList的实际元素数量
16 private int size;
17
18 //构造方法传入默认的capacity 设置默认数组大小
19 public ArrayList(int initialCapacity) {
20 super();
21 if (initialCapacity < 0)
22 throw new IllegalArgumentException("Illegal Capacity: "+
23 initialCapacity);
24 this.elementData = new Object[initialCapacity];
25 }
26
27 //无参数构造方法默认为空数组
28 public ArrayList() {
29 super();
30 this.elementData = EMPTY_ELEMENTDATA;
31 }
32
33 //构造方法传入一个Collection, 则将Collection里面的值copy到arrayList
34 public ArrayList(Collection<? extends E> c) {
35 elementData = c.toArray();
36 size = elementData.length;
37 // c.toArray might (incorrectly) not return Object[] (see 6260652)
38 if (elementData.getClass() != Object[].class)
39 elementData = Arrays.copyOf(elementData, size, Object[].class);
40 }
41
42 //下面主要看看ArrayList 是如何将数组进行动态扩充实现add 和 remove
43
44
45 public boolean add(E e) {
46 ensureCapacityInternal(size + 1); // Increments modCount!!
47 elementData[size++] = e;
48 return true;
49 }
50
51
52 public void add(int index, E element) {
53 rangeCheckForAdd(index);
54
55 ensureCapacityInternal(size + 1); // Increments modCount!!
56 System.arraycopy(elementData, index, elementData, index + 1,
57 size - index);
58 elementData[index] = element;
59 size++;
60 }
61
62 private void ensureCapacityInternal(int minCapacity) {
63 if (elementData == EMPTY_ELEMENTDATA) {
64 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
65 }
66
67 ensureExplicitCapacity(minCapacity);
68 }
69
70 private void ensureExplicitCapacity(int minCapacity) {
71 modCount++;
72
73 //超出了数组可容纳的长度,需要进行动态扩展
74 if (minCapacity - elementData.length > 0)
75 grow(minCapacity);
76 }
77
78 //这才是动态扩展的精髓,看到这个方法,ArrayList瞬间被打回原形
79 private void grow(int minCapacity) {
80 int oldCapacity = elementData.length;
81 //设置新数组的容量扩展为原来数组的1.5倍
82 int newCapacity = oldCapacity + (oldCapacity >> 1);
83 //再判断一下新数组的容量够不够,够了就直接使用这个长度创建新数组,
84 //不够就将数组长度设置为需要的长度
85 if (newCapacity - minCapacity < 0)
86 newCapacity = minCapacity;
87 //判断有没超过最大限制
88 if (newCapacity - MAX_ARRAY_SIZE > 0)
89 newCapacity = hugeCapacity(minCapacity);
90 //将原来数组的值copy新数组中去, ArrayList的引用指向新数组
91 //这儿会新创建数组,如果数据量很大,重复的创建的数组,那么还是会影响效率,
92 //因此鼓励在合适的时候通过构造方法指定默认的capaticy大小
93 elementData = Arrays.copyOf(elementData, newCapacity);
94 }
95
96 private static int hugeCapacity(int minCapacity) {
97 if (minCapacity < 0) // overflow
98 throw new OutOfMemoryError();
99 return (minCapacity > MAX_ARRAY_SIZE) ?
100 Integer.MAX_VALUE :
101 MAX_ARRAY_SIZE;
102 }
103
104
105 }
其实, ArrayList 的本质就是数组, ArrayList就是对数组进行动态的扩展,其add, get , remove 等等操作就是对数组的操作。至此,你还需要去记书籍上面所描述的ArrayList的特性了嘛? 如果还要记,那就弱爆了! ArrayList的一些特性都来源于数组:有序、元素可重复、插入慢、 索引快 等等一系列神马所谓的属性, 你懂了么?有木有恍然大悟的感觉
转载于:https://my.oschina.net/u/197668/blog/361193