日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

ArrayList源码学习

發(fā)布時間:2023/11/27 生活经验 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ArrayList源码学习 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

可增長數(shù)組結(jié)構(gòu)

實現(xiàn):
  1. 內(nèi)部采用數(shù)組的方式。
    1.1 添加元素,會每次校驗容量是否滿足, 擴容規(guī)則是當(dāng)前數(shù)組長度+當(dāng)前數(shù)組長度的二分之一。容量上限是Integer.MAX_VALUE。 copy使用Arrays.copy的api
    1.2 刪除元素
      1.2.1 通過對象刪除。遍歷數(shù)組,刪除第一個匹配的對象
      1.2.3 通過下標(biāo)刪除。判斷下標(biāo)是否越界。
        使用 System.arraycopy進(jìn)行copy, 并將元素的最后一位設(shè)置為null.供gc回收
  2. 內(nèi)部是同步[modCount]
    2.1 ArrayList數(shù)據(jù)結(jié)構(gòu)變化的時候,都會將modCount++。
    2.2 采用Iterator遍歷的元素, next()會去檢查集合是否被修改[checkForComodification],如果集合變更會拋出異常
    類似于數(shù)據(jù)庫層面的 樂觀鎖 機制。 可以通過 Iterator的api去刪除元素
3. 數(shù)組結(jié)構(gòu),內(nèi)部存儲數(shù)據(jù)是有序的,并且數(shù)據(jù)可以為null,支持添加重復(fù)數(shù)據(jù)

modCount作用:
https://www.cnblogs.com/zuochengsi-9/p/7050351.html

?

源碼分析

package xin.rtime.collections.list;import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;// 模擬ArrayList的實現(xiàn)
public class ArrayList<E> {private transient int modCount = 0;    // 修改次數(shù)private transient Object[] elementData; // 數(shù)據(jù)集合private static final Object[] EMPTY_ELEMENTDATA = {}; // 默認(rèn)空數(shù)組private int size; // 數(shù)組實際個數(shù)private static final int DEFAULT_CAPACITY = 10; // 默認(rèn)長度private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;  // 數(shù)組最大長度// 默認(rèn)構(gòu)造函數(shù)public ArrayList() {elementData = EMPTY_ELEMENTDATA; // 默認(rèn)等于空集合
    }// 初始化指定長度public ArrayList(int initialCapacity) {if (initialCapacity < 0) // 長度小于0 拋異常throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);this.elementData = new Object[initialCapacity]; // new一個指定長度的對象數(shù)組
    }// 添加元素public boolean add(E e) {ensureCapacityInternal(size + 1);elementData[size++] = e; // 放置添加的元素return true;}// 刪除元素public boolean remove(E e) {if (e == null) {for (int index = 0; index < size; index++)if (elementData[index] == null) {  // 刪除 null
                    fastRemove(index);return true;}} else {for (int index = 0; index < size; index++)if (e.equals(elementData[index])) {   // eqals比較
                    fastRemove(index);return true;}}return false;}private void fastRemove(int index) {modCount++;int numMoved = size - index - 1;      // 當(dāng)前size - index - 1    數(shù)組從0開始if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index,numMoved);   // system arraycopyelementData[--size] = null; // clear to let GC do its work   gc回收
    }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; // clear to let GC do its workreturn oldValue;}// 獲取元素public E get(int index) {rangeCheck(index);   // index校驗return elementData(index);}@SuppressWarnings("unchecked")E elementData(int index) {return (E) elementData[index];}private void rangeCheck(int index) {if (index >= size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}private String outOfBoundsMsg(int index) {return "Index: "+index+", Size: "+size;}// 返回元素個數(shù)public int size() {return size;}// 判斷當(dāng)前容量是否能否裝下元素private void ensureCapacityInternal(int minCapacity) {if (elementData == EMPTY_ELEMENTDATA) // 空集合minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); // 10 傳入的
ensureExplicitCapacity(minCapacity);}// 提供外部遍歷public Iterator<E> iterator() {return new Itr();}private class Itr implements Iterator<E> {int cursor;       // index of next element to return    游標(biāo)int lastRet = -1; // index of last element returned; -1 if no such    最后元素下標(biāo)int expectedModCount = modCount;  // 當(dāng)前數(shù)組修改次數(shù)public boolean hasNext() {return cursor != size;  // 當(dāng)前游標(biāo)是否等于size
        }@SuppressWarnings("unchecked")public E next() {checkForComodification();   // 檢查數(shù)組是否被操作過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();}}final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}}// 判斷容量 擴容private void ensureExplicitCapacity(int minCapacity) {modCount++;  // 修改+1if (minCapacity - elementData.length > 0) // 當(dāng)前長度 大于 數(shù)組長度
            grow(minCapacity);}public void add(int index, E element) {rangeCheckForAdd(index);ensureCapacityInternal(size + 1);  // Increments modCount!!System.arraycopy(elementData, index, elementData, index + 1,size - index);elementData[index] = element;size++;}private void rangeCheckForAdd(int index) {if (index > size || index < 0)   // index 超出 size  或者  index 小于0 ---> 數(shù)組越界throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}public E set(int index, E element) {rangeCheck(index);   // 校驗index是否滿足
E oldValue = elementData(index);elementData[index] = element;return oldValue;}/**<<      :     左移運算符,num << 1,相當(dāng)于num乘以2>>      :     右移運算符,num >> 1,相當(dāng)于num除以2>>>    :     無符號右移,忽略符號位,空位都以0補齊*/// 擴容private void grow(int minCapacity) {int oldCapacity = elementData.length; // 當(dāng)前數(shù)組長度int newCapacity = oldCapacity + (oldCapacity >> 1);  // 新容量大小 = 原來長度 + 原來長度 右移一位,除以2if (newCapacity - minCapacity < 0)  // 新長度 - 傳的長度 小于  0newCapacity = minCapacity;   //
        if (newCapacity - MAX_ARRAY_SIZE > 0)  // 當(dāng)前長度超出最大容量newCapacity = hugeCapacity(minCapacity);// minCapacity is usually close to size, so this is a win:elementData = Arrays.copyOf(elementData, newCapacity);   // 拷貝原來數(shù)據(jù)
    }// 判斷容量private int hugeCapacity(int minCapacity) {if (minCapacity < 0) // overflowthrow new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}}

?

轉(zhuǎn)載于:https://www.cnblogs.com/LuisYang/p/10034514.html

總結(jié)

以上是生活随笔為你收集整理的ArrayList源码学习的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。