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的一些特性都来源于数组:有序、元素可重复、插入慢、 索引快 等等一系列神马所谓的属性, 你懂了么?有木有恍然大悟的感觉