ArrayList其实就那么一回事儿之源码浅析

来源:互联网 发布:vr技术与人工智能 编辑:程序博客网 时间:2024/06/15 10:47

  ArrayList 算是常用的集合之一了,不知作为javaner的你有没在百忙之中抽出一点时间看看ArrayList的源码呢。 如果看了,你会觉得其实ArrayList其实就那么一回事儿,对吧,下面就看看ArrayList的部分源码吧。

  

复制代码

  1 public class ArrayList extends AbstractList

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

0 0
原创粉丝点击