zoukankan      html  css  js  c++  java
  • ArrayList源码分析笔记(jdk1.8)

    1.特点:

      ArrayList 是一个动态数组,它是线程不安全的,允许元素为null

      可重复,插入有序

      读写快,增删慢

      扩容:默认容量 10,默认扩容1.5倍

      建议指定容量大小,减少扩容带来的性能消耗

    2.构造方法

      只分析复杂的

      public ArrayList(Collection<? extends E> c)

        c.toArray()  在Collection接口中定义的接口方法,ArrayList中调用的是Arrays.copyOf(elementData, size)方法(注:扩容也是使用此方法,高频率方法),调用的是System.arraycopy          

    public static native void arraycopy(Object src,  int  srcPos,
                                            Object dest, int destPos,
                                            int length);

    2.add

      每次 add之前,都会判断add后的容量,是否需要扩容

      默认扩容倍数1.5倍,如果扩容1.5倍后小于传入的容量大小,则使用传入的容量大小,单最大不能大于Integer.MAX_VALUE;

      每次扩容都会修改modCount

      public boolean add(E e)

      public void add(int index, E element)

    public void add(int index, E element) {
        rangeCheckForAdd(index);//越界判断 如果越界抛异常
    
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index); //将index开始的数据 向后移动一位
        elementData[index] = element;
        size++;
    }

      addAll同理都需要先判断ensureCapacityInternal方法进行判断是否需要扩容,然后System.arraycopy进行数组赋值扩容

    3.romove

      public E remove(int index)

      public boolean remove(Object o)

      都是通过System.arraycopy进行数组赋值来达到效果,删除后原来,尾部元素,置空,gc

      public boolean removeAll(Collection<?> c)

        通过循环,和w标记,保存两个集合的非共有元素,共有元素置为null,gc

    private boolean batchRemove(Collection<?> c, boolean complement) {
            final Object[] elementData = this.elementData;
            int r = 0, w = 0;
            boolean modified = false;
            try {
                for (; r < size; r++)
                    if (c.contains(elementData[r]) == complement)
                        elementData[w++] = elementData[r];
            } finally {
                // Preserve behavioral compatibility with AbstractCollection,
                // even if c.contains() throws.
                if (r != size) {
                    System.arraycopy(elementData, r,
                                     elementData, w,
                                     size - r);
                    w += size - r;
                }
                if (w != size) {
                    // clear to let GC do its work
                    for (int i = w; i < size; i++)
                        elementData[i] = null;
                    modCount += size - w;
                    size = w;
                    modified = true;
                }
            }
            return modified;
        }

    4.set和get

      modCount不会改变,效率高

    5.迭代器

      public Iterator<E> iterator() { return new Itr(); }

      内部类:private class Itr implements Iterator<E>

        modCount != expectedModCount会抛出并发修改异常ConcurrentModificationException

        先next,再remove(实质上是删除上一次next的元素),否则回报IllegalStateException异常

    6.与Vector区别

      Vector:线程安全,都在方法上加synchronized关键字

          扩容:默认容量10,默认2倍扩容

    int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                             capacityIncrement : oldCapacity);

    https://blog.csdn.net/zxt0601/article/list/2

    https://blog.csdn.net/ljcITworld/article/details/52041836

  • 相关阅读:
    用JavaScript往DIV动态添加内容
    【转】javascript入门系列演示·三种弹出对话框的用法实例
    ASP.Net:Table类的使用
    vs2010设置 "行号显示"
    HTML相对路径 当前目录、上级目录、根目录、下级目录表示法
    【转】算法基础(二):栈的应用 --- 迷宫解题
    【转】CSS中怎么让DIV居中
    【转】如何让DIV水平和垂直居中
    SQL : 在SQL Server 2008(Or Express)中如何Open并编辑数据表【转】
    SQL2005中设置自动编号字段【转】
  • 原文地址:https://www.cnblogs.com/soul-wonder/p/10020128.html
Copyright © 2011-2022 走看看