ArrayList扩容1.5倍

先写一个小案例

代码
package com.itheima.demo;

import java.lang.reflect.Field;
import java.util.ArrayList;

public class ArrayListDemo {

    public static void main(String[] args) {
        ArrayList list1 = new ArrayList<>();
        Integer capacity = getCapacity(list1);// 获取容量
        int size = list1.size();
        System.out.println("list1的容量:" + capacity);
        System.out.println("list1的大小:" + size);
        System.out.println("----------------------------");

        ArrayList list2 = new ArrayList<>();
        list2.add(1);
        capacity = getCapacity(list2);// 获取容量,arraylist初始化容量是10
        size = list2.size();
        System.out.println("list2的容量:" + capacity);
        System.out.println("list2的大小:" + size);
        System.out.println("----------------------------");

        ArrayList list3 = new ArrayList<>();

        capacity = getCapacity(list3);// 获取容量,arraylist初始化容量是10
        for (int i = 0; i < 10; i++) {
            list3.add(i);
        }
        capacity = getCapacity(list3);
        size = list3.size();
        System.out.println("list3的容量:" + capacity);
        System.out.println("list3的大小:" + size);
        System.out.println("----------------------------");

        ArrayList list4 = new ArrayList<>();
        for (int i = 0; i < 11; i++) {
            list4.add(i);
        }
        capacity = getCapacity(list4);// 获取容量
        size = list4.size();
        System.out.println("list4的容量:" + capacity);
        System.out.println("list4的大小:" + size);

    }

    // 获取list容量
    public static Integer getCapacity(ArrayList list) {
        Integer length = null;
        Class clazz = list.getClass();
        Field field;
        try {
            field = clazz.getDeclaredField("elementData");
            field.setAccessible(true);
            Object[] object = (Object[]) field.get(list);
            length = object.length;
            return length;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return length;
    }
}
运行结果

ArrayList扩容1.5倍_第1张图片
当ArrayList不为空时,并且它的大小不超过10时,它的容量都是10.但当大小从10增加到11时,容量变成了15,扩大了1.5倍.

ArrayList的源代码

   /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return true (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        ensureCapacityInternal(size + 1); 
         //调用了一ensureCapacityInternal方法,实现list的容量换算,继续往下点击源代码
        elementData[size++] = e;
        return true;
    }

    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);//不管怎么样,最后都要走这一步,继续往下点击
 private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);//最后时限扩容的是grow,所以继续往下看grow的源码
    }
  private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);//新容量扩大到原容量的1.5倍,右移一位相关于原数值除以2。
        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);
    }

从案例和源代码来说,ArrayList的扩容是原来的1.5倍,当然,实际操作中,ArrayList扩容可能大于1.5倍,毕竟ArrayList调用add时,所涉及到的代码不止上面这一小点.

你可能感兴趣的:(集合)