当前位置:  首页>> 技术小册>> Java语言基础10-Java中的集合

4.4.1 概述

  • ArrayList 具备了List接口的特性(有序、重复、索引)。
  • ArrayList 集合底层的实现原理是数组,大小可变。
  • ArrayList 的特点:查询速度快、增删慢。
  • ArrayList 在 JDK8 前后的实现区别:
    • JDK7 :ArrayList 像饿汉式,直接创建了一个初始容量为 10 的数组,每次扩容是原来长度的 1.5 倍。
    • JDK8 :ArrayList 像懒汉式,一开始创建一个长度为 0 的数组,当添加第一个元素的时候再创建一个容器为 10 的数组,每次扩容是原来长度的 1.5 倍。
  • ArrayList 是线程不安全的集合,运行速度快。

4.4.2 ArrayList 的类成员变量

  • 默认容量:
  1. private static final int DEFAULT_CAPACITY = 10;
  • 空数组:
  1. private static final Object[] EMPTY_ELEMENTDATA = {};
  • 默认容量的空数组:
  1. private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
  • ArrayList 集合中的核心数组:
  1. transient Object[] elementData;
  • 记录数组中存储个数:
  1. private int size;
  • 数组扩容的最大值:
  1. private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

4.4.3 ArrayList 类的构造方法

  • 无参构造方法:
  1. public ArrayList() {
  2. this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
  3. }
  • 传入指定容量的构造方法:
  1. public ArrayList(int initialCapacity) {
  2. if (initialCapacity > 0) {
  3. this.elementData = new Object[initialCapacity];
  4. } else if (initialCapacity == 0) {
  5. this.elementData = EMPTY_ELEMENTDATA;
  6. } else {
  7. throw new IllegalArgumentException("Illegal Capacity: "+
  8. initialCapacity);
  9. }
  10. }

4.4.4 ArrayList 类的 add 方法

  1. public boolean add(E e) {
  2. // 检查容量 size初始化的时候是0,那么size+1就是1
  3. ensureCapacityInternal(size + 1); // Increments modCount!!
  4. // 将元素添加到数组中,size计数器++
  5. elementData[size++] = e;
  6. return true;
  7. }
  1. // minCapacity此时是1
  2. private void ensureCapacityInternal(int minCapacity) {
  3. // 如果存储元素的数据 == 默认的空的数组,无参构造器中赋值
  4. if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
  5. // 返回DEFAULT_CAPACITY=10和minCapacity=1的最大值,即10
  6. minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
  7. }
  8. // 扩容
  9. ensureExplicitCapacity(minCapacity);
  10. }
  11. private void ensureExplicitCapacity(int minCapacity) {
  12. modCount++;
  13. // overflow-conscious code
  14. // 10- 数组的长度0 > 0
  15. if (minCapacity - elementData.length > 0)
  16. // 传入10
  17. grow(minCapacity);
  18. }
  19. private void grow(int minCapacity) {
  20. // overflow-conscious code
  21. // 数组的原来长度 0
  22. int oldCapacity = elementData.length;
  23. // 新容量 = 数组原来的长度 + 数组原来的长度 / 2
  24. int newCapacity = oldCapacity + (oldCapacity >> 1); // 0
  25. if (newCapacity - minCapacity < 0) // 0 -10 < 0
  26. newCapacity = minCapacity; // 新容量 = 10
  27. if (newCapacity - MAX_ARRAY_SIZE > 0) // 判断是否超过最大容量
  28. newCapacity = hugeCapacity(minCapacity);
  29. // minCapacity is usually close to size, so this is a win:
  30. elementData = Arrays.copyOf(elementData, newCapacity); // 数组的复制
  31. }

4.4.5 ArrayList 类的 get 方法

  1. public E get(int index) {
  2. // 检查索引
  3. rangeCheck(index);
  4. // 返回数组中指定索引处的元素
  5. return elementData(index);
  6. }

4.4.6 ArrayList 类的 set 方法

  1. public E set(int index, E element) {
  2. // 检查索引
  3. rangeCheck(index);
  4. // 获取旧的元素
  5. E oldValue = elementData(index);
  6. // 将新的元素设置到指定的索引处
  7. elementData[index] = element;
  8. // 返回旧的元素
  9. return oldValue;
  10. }

4.4.7 ArrayList 类的 remove 方法

  1. public E remove(int index) {
  2. // 检查索引
  3. rangeCheck(index);
  4. modCount++;
  5. // 获取旧的元素
  6. E oldValue = elementData(index);
  7. int numMoved = size - index - 1;
  8. if (numMoved > 0)
  9. // 将index后面的元素依次复制到前面
  10. System.arraycopy(elementData, index+1, elementData, index,
  11. numMoved);
  12. // 最后一个元素设置为null
  13. elementData[--size] = null; // clear to let GC do its work
  14. // 返回旧的元素
  15. return oldValue;
  16. }