zoukankan      html  css  js  c++  java
  • JDK8集合类源码解析

    ArrayList主要要注意以下几点:

    1构造方法

    2添加add(E e) 

    3 获取 get(int index)

    4 删除 remove(int index)    ,   remove(Object o)

    5 判断是否存在 contains(Object o)

    6 遍历

    ======================================

    底层采用数组实现。

    1构造方法

    有三个 分别是 指定数组大小;不指定(创建一个空的,添加元素的时候再扩容);从一个集合创建

    这里顺便说下集合的继承关系

     Collection

        |--List

           |--ArrayList

           |--Vector

           |--LinkedList

        |--Set

           |--HashSet

           |--TreeSet

    2添加add(E e) 

     public boolean add(E e) {
            ensureCapacityInternal(size + 1);  // 先判断容量够不够
            //添加到末尾
            elementData[size++] = e;
            return true;
    }
     private void ensureCapacityInternal(int minCapacity) {
            if (elementData == EMPTY_ELEMENTDATA) { //空就创建一个长度为10的数组
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }
    
            ensureExplicitCapacity(minCapacity);
        }
    
        private void ensureExplicitCapacity(int minCapacity) {
            modCount++; //操作计数+1 用于在遍历的时候判断是否有添加或者删除操作
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);//扩容
        }
    
        private void grow(int minCapacity) {
            int oldCapacity = elementData.length;
            int newCapacity = oldCapacity + (oldCapacity >> 1);//变成原来的1.5倍
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            if (newCapacity - MAX_ARRAY_SIZE > 0)//如果新容量 MAX_ARRAY_SIZE还大 那么新容量就设置为Integer.MAX_VALUE
                newCapacity = hugeCapacity(minCapacity);
            //复制数据
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
    

      

    3 获取 get(int index)

      public E get(int index) {

            rangeCheck(index); //看数组是否越界

            return elementData(index);

        }

    4 删除 remove(int index)    ,   remove(Object o)

    public E remove(int index) {
      rangeCheck(index);
    modCount++;
     E oldValue = elementData(index);
     int numMoved = size - index - 1; //需要移动的元素的个数
    if (numMoved > 0)
     System.arraycopy(elementData, index+1, elementData, index,numMoved);//从删除的元素到最后的元素全部前移
            elementData[--size] = null; // 方便gc回收
            return oldValue;
    }
    

      

     remove(Object o) 先遍历找到该元素,然后在删除 ,删除方法和上面的方法类似,需要移动数组(如果不是最后一个元素的话)

    5 判断是否存在 contains(Object o)

    //遍历 找到了就返回下标 不然返回 -1
    public boolean contains(Object o) {
            return indexOf(o) >= 0;
        }
        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;
        }
    

    6遍历

     int cursor;       // 遍历标志位
            int lastRet = -1; // index of last element returned; -1 if no such
            int expectedModCount = modCount;
    
            public boolean hasNext() {
                return cursor != size;
            }
    
            @SuppressWarnings("unchecked")
            public E next() {
                checkForComodification();
                int i = cursor;
                if (i >= size)
                    throw new NoSuchElementException();
                Object[] elementData = ArrayList.this.elementData;
                if (i >= elementData.length)
                    throw new ConcurrentModificationException();
                cursor = i + 1;
                return (E) elementData[lastRet = i];
            }
    
            public void remove() {
                if (lastRet < 0)
                    throw new IllegalStateException();
                checkForComodification();
    
                try {
                    ArrayList.this.remove(lastRet);
                    cursor = lastRet;
                    lastRet = -1;
                    expectedModCount = modCount;
                } catch (IndexOutOfBoundsException ex) {
                    throw new ConcurrentModificationException();
                }
            }
     注意两点:       1遍历的时候 如果要删除元素 要使用Iterator
                    2只有调用了next才能调用remove
    

      

    最佳实践

    1如果能够预知集合大小,创建的时候最好使用指定大小的构造函数,能够提高性能(没有了扩容)

    2线程不安全,多线程环境建议使用CopyOnWriteArrayList

    3遍历集合 如果要删除元素 要使用Iterator

    4底层基于数值实现,增删慢 获取快(仅限于下标方式)

  • 相关阅读:
    python 匿名函数lambda()
    python列表推导式
    python数组的基本操作一(添加,扩展,插入)
    Python的数字类型
    Python初识以及Windows安装教程
    字典简单使用
    two sum(LeetCode)
    python读写文件
    C++ volatile关键字(转)
    实验一
  • 原文地址:https://www.cnblogs.com/javabigdata/p/7086510.html
Copyright © 2011-2022 走看看