Java集合源码剖析

目录

Java集合源码剖析

ArrayList

LinkedList

HashMap

HashTable

ConcurrentHashMap


Java集合源码剖析

Java集合源码剖析_第1张图片

ArrayList

底层结构:ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素(动态数组)。

  • ArrayList底层是数组,允许元素是null,能够动态扩容

  • size、isEmpty、get、set、add 等方法时间复杂度都是 O (1)

  • 非线程安全,并发修改时,会抛出ConcurrentModificationException

初始化

  • ArrayList objectName =new ArrayList<>();ArrayList无参初始化的时候,默认是空数组,并没有初始化容量大小,容量是在第一次添加元素才进行初始化。

  • ArrayList objects1 = new ArrayList<>(50);,ArrayList有参初始化的时候,数组容量大小为该参数大小。

    添加元素

    ArrayList中添加元素我们使用add()方法:

     //ArrayList的add()源码
         public boolean add(E e) {
             ensureCapacityInternal(size + 1);  // Increments modCount!!
             elementData[size++] = e;
             return true;
         }
     ​
     // 进入ensureCapacityInternal(size + 1)方法看看
     // elementData:数组缓冲区,存储数组列表中的元素。数组列表的容量是这个数组缓冲区的长度。
         private void ensureCapacityInternal(int minCapacity) {
             ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
         }
     ​
     // 进入calculateCapacity(elementData, minCapacity)方法看看
         private static int calculateCapacity(Object[] elementData, int minCapacity) {
             if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                 return Math.max(DEFAULT_CAPACITY, minCapacity);
             }
             // 很明显,如果数组为空,就比较默认容量10和当前ArrayList的长度+1,返回大的。
             // 这里的意思就是要保证容量至少是10
             // private static final int DEFAULT_CAPACITY = 10;
             // 如果容量大于默认容量
             return minCapacity;
             
         }
     ​
     // 返回ensureCapacityInternal(int minCapacity)
     // ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
         private void ensureExplicitCapacity(int minCapacity) {
             // 计算数组结构改变次数
             modCount++;
     ​
             // overflow-conscious code
             if (minCapacity - elementData.length > 0)
                 // 增加容量,以确保它至少可以容纳最小容量参数指定的元素数量。
                 grow(minCapacity);
         }
     ​
     // 这是扩容机制grow(minCapacity);
         private void grow(int minCapacity) {
             // overflow-conscious code
             // 旧容量
             int oldCapacity = elementData.length;
             // 新容量oldCapacity >> 1,右移是除,新容量是旧容量的1.5倍。
             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:
             // 拷贝数组,数组赋值
             elementData = Arrays.copyOf(elementData, newCapacity);
         }
     ​
         private static int hugeCapacity(int minCapacity) {
             if (minCapacity < 0) // overflow
                 throw new OutOfMemoryError();
             // 容量超了就扩到最大,不管你了,爱咋咋地。
             return (minCapacity > MAX_ARRAY_SIZE) ?
                 Integer.MAX_VALUE :
                 MAX_ARRAY_SIZE;
         }

    看完add()方法源码之后,我们知道,ArrayList在添加元素之前会计算数组的容量,看容量是否足够,不够的话会扩容,扩容一般是扩容到1.5倍,不够的话将直接扩容到size+1大小,如果minCapacity > MAX_ARRAY_SIZE,那就直接扩容到最大了。

    删除元素

    // remove()源码  
     // 注释:如果指定元素存在,则从该列表中删除该元素的第一个匹配项。 如果列表中不包含该元素,则该元素不变。 更正式地说,删除索引i最低的元素,这样(o==null ? Get (i)==null: o.equals(Get (i)))(如果存在这样的元素)。 如果该列表包含指定的元素,则返回true(或者,如果该列表因调用而发生更改,则返回true)。  
         public boolean remove(Object o) {
             // 为空,找到第一个为null的删除
             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;
         }
    
    
    

    修改元素

    //set()方法修改元素
     // 注释:将此列表中指定位置的元素替换为指定的元素。
         public E set(int index, E element) {
             // 检测索引是否在范围内
             rangeCheck(index);
         
             E oldValue = elementData(index);
             elementData[index] = element;
             return oldValue;
         }
    
    
    

    查找元素

     // get()
         public E get(int index) {
             rangeCheck(index);
     ​
             return elementData(index);
         }

    LinkedList

    LinkedList底层结构是双向链表,添加、删除元素效率高;按照索引查询效率低。可以两个方向查询。

    初始化

    LinkedList的初始化:
    
    LinkedList linkedList = new LinkedList<>();:构建一个空的链表
    
    初始化时添加一个集合
    
         public LinkedList(Collection c) {
             this();
             addAll(c);
         }
    

    添加元素

       
    // add(),将指定的元素追加到此列表的末尾。
       public boolean add(E e) {
             linkLast(e);
             return true;
         }
     ​
     ​
         /**
          * Links e as last element.
          */
         void linkLast(E e) {
             final Node l = last;
             final Node newNode = new Node<>(l, e, null);
             last = newNode;
             if (l == null)
                 first = newNode;
             else
                 l.next = newNode;
             size++;
             modCount++;
         }

    删除元素

     ​
         
    /**
          * Removes the first occurrence of the specified element from this list,
          * if it is present.  If this list does not contain the element, it is
          * unchanged.  More formally, removes the element with the lowest index
          * {@code i} such that
          * (o==null ? get(i)==null : o.equals(get(i)))
          * (if such an element exists).  Returns {@code true} if this list
          * contained the specified element (or equivalently, if this list
          * changed as a result of the call).
          *
          * @param o element to be removed from this list, if present
          * @return {@code true} if this list contained the specified element
          */
         public boolean remove(Object o) {
             if (o == null) {
                 for (Node x = first; x != null; x = x.next) {
                     if (x.item == null) {
                         unlink(x);
                         return true;
                     }
                 }
             } else {
                 for (Node x = first; x != null; x = x.next) {
                     if (o.equals(x.item)) {
                         unlink(x);
                         return true;
                     }
                 }
             }
             return false;
         }
     ​
     // 元素的删除关键在unlink(x)方法
     ​
         /**
          * Unlinks non-null node x.
          */
         E unlink(Node x) {
             // assert x != null;
             final E element = x.item;
             final Node next = x.next;
             final Node prev = x.prev;
     ​
             if (prev == null) {
                 first = next;
             } else {
                 prev.next = next;
                 x.prev = null;
             }
     ​
             if (next == null) {
                 last = prev;
             } else {
                 next.prev = prev;
                 x.next = null;
             }
    

    你可能感兴趣的:(java)