zoukankan      html  css  js  c++  java
  • ArrayList源码分析

    public class ArrayList<E> extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable

     Serializable

    这是源码里面的实现了这个接口我们就可以进行序列话和反序列化了

    Cloneable

    这是源码里面的实现了这个接口可以复制对象了复写clone方法,他本地有一个接口就可以有一个本地方法调用native方法可以克隆

    深克隆:克隆对象里面的对象的引用为新的引用

    浅克隆:克隆对象里面的对象的引用为新的引用老的引用

    RandomAccess

    这是源码里面的实现了这个接口理解为

    使用fori循环遍历比迭代器遍历快

    会判断走那种遍历

    indexedBinarySerach(list,key)或iteratorBinarySerach(list,key)方法

    添加方法add(E e)

    List<String> list = new ArrayList<>();

    这个的时候会创建一个新的空数组

        public boolean add(E e) {
            // 判断是否需要扩容
            ensureCapacityInternal(size + 1);
            // 将新元素追加到相应的数组中
            elementData[size++] = e;
            return true;
        }

    第一次添加调用调用初始化长度和扩容

        // minCapacity = size + 1
        private void ensureCapacityInternal(int minCapacity) {
            ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
        }
    
        private static int calculateCapacity(Object[] elementData, int minCapacity) {
            // 如果当前数组为空,则所需容量就是默认容量
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                return Math.max(DEFAULT_CAPACITY, minCapacity);
            }
            return minCapacity;
        }
    
        private void ensureExplicitCapacity(int minCapacity) {
            modCount++;
    
            // 增加元素所需空间不足,则需扩容
            if (minCapacity - elementData.length > 0)
                // 真正的扩容方法
                grow(minCapacity);
        }

    扩容

        // 数组默认的最大长度
        private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    
        private void grow(int minCapacity) {
            // 旧数组的长度
            int oldCapacity = elementData.length;
            // 扩容为原来的1.5倍
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            // 判断新的数组容量是否达到需求
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            // 判断新容量是否溢出
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            // 调用Arrays.copyOf()方法,将elementData数组复制到一个新数组
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
    
        private static int hugeCapacity(int minCapacity) {
            if (minCapacity < 0)
                throw new OutOfMemoryError();
            return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
        }

    添加方法add(index i ,E e)

    这个方法也是很简单的大概是需要判断是否扩容

    然后把索引位置的数组拷贝到后面

    比如说我们需要把索引为1的数据改为4

    addAll

    差不多的

    get

    E elementData(int index) {
            return (E) elementData[index];
        }
    
        /**
         * Returns the element at the specified position in this list.
         *
         * @param  index index of the element to return
         * @return the element at the specified position in this list
         * @throws IndexOutOfBoundsException {@inheritDoc}
         */
        public E get(int index) {
            rangeCheck(index);
    
            return elementData(index);
        }

    很简单第一个方法判断是否越界,第二个直接通过索引获得

  • 相关阅读:
    Python3.x和Python2.x的区别
    python 列表 元组 字典
    Wireshark TCP报文到达确认(ACK)机制
    Wireshark Tcp三次握手
    Python Vim配置 Win7x64
    Workstation guest fails to restart or resume
    python 枚举目录下所有子目录和文件,输出列表
    Python按行读文件 高级
    python 注释
    十一、设备初始化(ADK4.0)
  • 原文地址:https://www.cnblogs.com/xiaoruirui/p/15138393.html
Copyright © 2011-2022 走看看