• 集合—ArrayList


    ArrayList也叫作数组列表

     public static void main(String[] args) {
            List list1 = new ArrayList<String>();
            list1.add("a");
            //0100=4 右移1位 0010=2
            System.out.println(4>>1); //相当于 4/2
            //0010=2 左移1位 0100=4
            System.out.println(2<<1); //相当于 2*2
            
        }
      
        transient Object[] elementData;
        private int size;
        private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
        /**
         * Default initial capacity.
         */
        private static final int DEFAULT_CAPACITY = 10;
        protected transient int modCount = 0;
        private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
        public boolean add(E e) {
            // 保证数组的容量始终够用
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            // size是elementData数组中元素的个数,初始化为0
            elementData[size++] = e;
            return true;
        }
        
        private void ensureCapacityInternal(int minCapacity) {
            // 如果数组没有元素,给数组一个默认大小,会选择实例化时的值与默认大小中较大值
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }
            // 保证容量够用
            ensureExplicitCapacity(minCapacity);
        }
        
        private void ensureExplicitCapacity(int minCapacity) {
            // modCount是elementData数组发生size更改的次数
            modCount++;
            // 如果当前数组长度比原数组长度大,则进行扩容
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
        
        private void grow(int minCapacity) {
            int oldCapacity = elementData.length;
            // 新的数组长度 会进行行1.5倍扩容,通过向右移位实现/2操作
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            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:这里只用Arrays.copyOf
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
        
        public void add(int index, E element) {
            // 判断index的值是否合法,如果不合法则抛出异常
            rangeCheckForAdd(index);
            // 保证容量够用
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            // 从第index位置开始,将元素往后移一个位置
            System.arraycopy(elementData, index, elementData, index + 1,
                             size - index);
            // 把要插入的元素e放在第index的位置
            elementData[index] = element;
            // 数组的元素个数加1
            size++;
        }
        
        /**
         * A version of rangeCheck used by add and addAll.
         */
        private void rangeCheckForAdd(int index) {
            if (index > size || index < 0)
                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        }
        /**
         * Constructs an IndexOutOfBoundsException detail message.
         * Of the many possible refactorings of the error handling code,
         * this "outlining" performs best with both server and client VMs.
         */
        private String outOfBoundsMsg(int index) {
            return "Index: "+index+", Size: "+size;
        }

    ArrayList是基于数组实现的,是一个动态数组,其容量能够自动增长 ArrayList不是线程安全的,只能用在单线程环境下,多线程环境需要使用Collections同步方法。Collections.synchronizedList(List l)返回一个线程安全的ArrayList。如果是读写比例比较大的话(锁粒度降级),则可以考虑CopyOnwriteArrayList。

    1. 默认容量是10
    2. ArrayList每次增加元素的时候,都需要调用ensureCapacity方法来确保足够的容量。当容量不足的时候,就设置新的容量为旧的的容量的1.5倍加1,如果设置的容量仍然不够,那么直接设置为传入的参数,而后用Arrays.copyOf方法将元素拷贝到新的数组。建议:在能够实现确定元素数量的情况下使用ArrayList,否则使用LinkedList。
    3. Arrays.copy()方法在方法的内部又创建了一个长度等长的数组,调用System.arraycopy方法完成新数组元素的复制。该方法的实际上调用native方法中C的memmove函数,在复制大数组的时候强烈建议使用该方法进行数组的复制。效率高。
    4. ArrayList是基于数组实现的,支持随机访问,查找效率高,但是插入删除效率低。
    5. ArrayList一般应用于查询较多但插入以及删除较少情况,如果插入以及从删除较多则建议使用LinkedList.
    6. ArrayList在知道长度范围实例化的时候带上长度 new ArrayList(128),这样降低了内存碎片和内存拷贝的次数.
  • 相关阅读:
    Android
    十大基础有用算法之迪杰斯特拉算法、最小生成树和搜索算法
    【随想】android是个什么东西,andorid机制随想
    【Unity3D】【NGUI】Atlas的动态创建
    Java集合01----ArrayList的遍历方式及应用
    JAVA线程
    VC++的project文件
    selector的button选中处理问题
    单元測试和白盒測试相关总结
    leetCode(40):Path Sum
  • 原文地址:https://www.cnblogs.com/atomicbomb/p/9917076.html
Copyright © 2020-2023  润新知