zoukankan      html  css  js  c++  java
  • java arraylist源码记录

    1. ArrayList 实现了RandomAccess接口, RandomAccess接口用于标记是否可以随机访问

    2. 继承了AbstractList类, 因此获取了modcount , modcount用于实现快速失败机制, 如果list有修改, 那么modcount自增

    3. ArrayList不支持并发, 是非线程安全的

    4. 支持存放null元素

    5. 扩容, 每次都是原来大小的1.5倍

    public void ensureCapacity(int minCapacity) {
            //如果elementData不等于EMPTY_ELEMENTDATA(因为初始化时有可能等于), 那么minExpand为0或者DEFAULT_CAPACITY
            //如果elementData不为空minExpand为0, 可以用这个来处理minCapacity为负数的情况
            //如果elementData为空, 那么就是默认容量
            int minExpand = (elementData != EMPTY_ELEMENTDATA)
                    // any size if real element table
                    ? 0
                    // larger than default for empty table. It's already supposed to be
                    // at default size.
                    : DEFAULT_CAPACITY;
    
            //如果最小容量大于minExpand, 那么进行明确扩容
            if (minCapacity > minExpand) {
                ensureExplicitCapacity(minCapacity);
            }
        }
    
        //已确定扩容minCapacity
        private void ensureExplicitCapacity(int minCapacity) {
            modCount++; //修改次数加1
    
            // overflow-conscious code
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
    
        private void grow(int minCapacity) {
            // overflow-conscious code
            int oldCapacity = elementData.length;
            //newCapacity为oldCapacity的1.5倍, 这里有可能会溢出为-1
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            ....
        }

    6. lastIndexOf, contains, indexOf方法用于查找, 时间复杂度均为O(N), 使用对象的equals方法进行比较
    7. clone() 方法为深复制, 所谓深复制和浅复制的区别在于复制内部引用对象时的不同, 深复制会将原来的对象重新clone一份, 让复制对象的引用指向新对象, 而浅复制仅仅复制引用, 仍指向原来的对象. java Object中的clone方法为浅复制

    8. set() 和 get() 为O(1)的时间复杂度

    9. 调用ensureCapacityInternal(int) 会使modCount+1. ArrayList中的添加元素都会调用这个函数 ,例如add(object)和add(int,Object)

    10. add(Object) 和add(int,Object)的时间复杂度为O(N), 因为底层数组的复制移动

    11. remove(int)方法也会使modCount+1, 时间复杂度为O(N) , 同时内部使用elementData[--size] = null;用来防止内存泄漏, 以便gc释放内存

    12. remove(Object) 使用了fastRemove非法, fastRemove如果未找到删除元素, 那么modCount是不会变的, 反之modCount+1 , 之所以fastRemove称之为fast是因为使用了System.arrayCopy进行元素移动, System.arrayCopy是一个native方法, 可以躲避java访问数组时的下标检查.

    13. clear方法, modCount+1

    14. addAll(...) 都会调用ensureCapacityInternal方法,  从而使modCount+1, O(N)的时间复杂度

    15. removeAll(object)//补集和retainAll(object)//交集 都可以使用batchRemove方法, O(N^2)的时间复杂度, modCount+1.

    16. 快速失败机制体现在容器的遍历中, Iterator会在对象初始化过程中保存当前容器的modCount, 并在每次遍历检查modCount, 如果两者不一致, 那么说明容器在遍历时被修改, 抛出ConcurrentModificationException.

       private class Itr implements Iterator<E> {
    
            int expectedModCount = modCount;
    
            public E next() {
                checkForComodification();
                int i = cursor;
               ...
            }
    
            public void remove() {
               ...
                checkForComodification();
    
               ...
            }
    
            final void checkForComodification() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
        }
  • 相关阅读:
    CentOS-Docker安装RabbitMQ(单点)
    CentOS-关闭防火墙和禁用安全策略
    CentOS-Docker搭建VeryNginx
    CentOS7-磁盘扩容(LVM-非空目录拓展卷空间大小)
    (六十二)Activity的启动模式(转载自http://blog.csdn.net/android_tutor/article/details/6310015)
    (一)关于SWT程序的基本架构,如何使用控件以及使用Image,Font,Color等图形资源内容
    (六十一)eclipse老是卡顿的问题解决办法
    (六十一)Activity启动模式 及 Intent Flags 与 栈 的关联分析(转载自:http://blog.csdn.net/vipzjyno1/article/details/25463457)
    (六十)工具方法---隐藏软键盘
    iOS 语音朗读
  • 原文地址:https://www.cnblogs.com/iamzhoug37/p/5646436.html
Copyright © 2011-2022 走看看