zoukankan      html  css  js  c++  java
  • List源码学习之ArrayList

      ArrayList 内部结构为一个可重复的对象数组(可存空对象)。

    内部有以下几个参数:

    /**
    * 默认初始容量
    */
    private static final int DEFAULT_CAPACITY = 10;

    /**
    * 用于空实例的共享空数组实例
    */
    private static final Object[] EMPTY_ELEMENTDATA = {};

    /**
    * 存储数组列表元素的数组缓冲区。数组列表的容量是这个数组缓冲区的长度
    */
    private transient Object[] elementData;

    /**
    * 数组列表的大小
    *
    * @serial
    */
    private int size;

    //默认数组最大值
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    分析几个内部方法:

    1.indexOf(Object o):

    public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

    循环对象数组进行比较,返回第一个匹配到的对象的下标,若未匹配到返回-1,提供给contains(Object o) 方法。

    2.add(Object o): 添加前需要对容量进行容量检查 扩展容量。

    public boolean add(E e) {
            ensureCapacityInternal(size + 1);  // 确保内部容量:
            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++; if (minCapacity - elementData.length > 0) grow(minCapacity); }
    //扩展
    private void grow(int minCapacity) { int oldCapacity = elementData.length;
         //扩展容量为之前容量的3/2  int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity;
         //如果扩展后的容量大于数组最大值,扩展至最大容量 if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // elementData = Arrays.copyOf(elementData, newCapacity); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError();
        如果最小容量大于数组最大值,则扩展至Integer的最大值否则扩展至数组默认最大值 return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
    
    

    3.remove(int index):按数组下标移除对象元素,

    public E remove(int index) {
        //边界检查 rangeCheck(index);      //修改次数+1 modCount
    ++; E oldValue = elementData(index); int numMoved = size - index - 1; if (numMoved > 0)
           //数组拷贝 System.arraycopy(elementData, index
    +1, elementData, index, numMoved);
         //清空最后一位 elementData[
    --size] = null; // clear to let GC do its work return oldValue; }

    4.remove(Object o):按对象移除,只移除匹配到的第一个相同对象

    public boolean remove(Object o) {
    //从前往后匹配,若匹配到则根据下标进行删除。
    if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; }

    private void fastRemove(int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work }

    5.addAll(Collection<? extends E> c):将指定集合中的所有元素追加到数组的末尾

    public boolean addAll(Collection<? extends E> c) {
            Object[] a = c.toArray();
            int numNew = a.length;
         //扩容 ensureCapacityInternal(size
    + numNew); // Increments modCount
         //数组拷贝 System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; }

    6.addAll(int index, Collection<? extends E> c):从数组的某个位置添加指定集合

    public boolean addAll(int index, Collection<? extends E> c) {
            rangeCheckForAdd(index);
        
         //将集合转化为对象数组 Object[] a
    = c.toArray(); int numNew = a.length;
         //扩容 ensureCapacityInternal(size
    + numNew); // Increments modCount      //将原数组index之后的数据拷贝至index+numNew之后 int numMoved = size - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew, numMoved);      //将指定数组添加至原数组 System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; }

    进阶之路从此开始,路在脚下早已铺好,走与不走全看你想不想欣赏沿途的风景———————AmbitiousMice

  • 相关阅读:
    jQuery的DOM操作
    jQuery的样式篇
    DOM对象控制HTML
    线程属性
    Glib动态加载模块(插件)
    linux 进程与线程命令
    error: server certificate verification failed.
    Qt qmake高级应用(翻译)
    Linux下设置QT环境变量
    pro、pri、prf、prl文件(qmake)
  • 原文地址:https://www.cnblogs.com/AmbitiousMice/p/8044522.html
Copyright © 2011-2022 走看看