最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于java構(gòu)造方法Vector刪除元素源碼分析

 更新時間:2021年09月09日 15:04:15   作者:叫我王員外就行  
這篇文章主要介紹了基于java構(gòu)造方法中對Vector刪除元素的源碼分析,有需要的朋友可以借鑒參考下,希望可以有所幫助,祝大家早日升職加薪

(注意:本文基于JDK1.8) 

前言

包括迭代器中的remove()方法,以及刪除單個元素、刪除多個元素、刪除所有元素、刪除不包含的所有元素的方法,Vector中共計10個對外的API可以用于刪除元素,今天一起分析每一個刪除元素的方法是如何實現(xiàn)的!

remove(int)方法分析

    public synchronized E remove(int index) {
        modCount++;
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);
        E oldValue = elementData(index);
        int numMoved = elementCount - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--elementCount] = null; // Let gc do its work
 
        return oldValue;
    }

用于刪除指定下標(biāo)單個元素的方法,傳入的參數(shù)index表示元素的下標(biāo),第一個元素的下標(biāo)是0,這個基礎(chǔ)知識點(diǎn)不要忘記哦

1、為fail-fast機(jī)制保駕護(hù)航

modCount是Vector對象持有的一個int變量,它本身位于Vector的父類AbstractList中,此處增加1,表示Vector的元素狀態(tài)發(fā)生改變,迭代器那里會使用fail-fast,防止多線程下即遍歷又刪除,也防止單線程下,一邊遍歷元素、一邊刪除元素

2、檢查下標(biāo)是否存在元素

檢查傳入的下標(biāo)index是否存在元素,當(dāng)index與elementCount相等或者大于elementCount,此處的index并沒有元素,所以不能刪除沒有元素的位置,此處作者拋出ArrayIndexOutOfBoundsException對象,為此告知調(diào)用者,你傳入的下標(biāo)根本沒有元素,怎么刪除呢?

3、保存刪除的元素到局部變量

調(diào)用elementData元素,并傳入下標(biāo)index,獲得指定下標(biāo)處的元素,并由局部變量oldValue負(fù)責(zé)保存

4、計算需要挪動元素的數(shù)量

使用表示元素總數(shù)的elementCount減去index、減去1,得到需要挪動元素的數(shù)量并存儲到局部變量numMoved

5、挪動元素

如果需要挪動元素,就將index下標(biāo)后面的所有元素向前挪動(復(fù)制)

6、減少元素總數(shù)值

先將元素總數(shù)elementCount減去1

7、將持有元素的引用,賦值為null

將Vector對象持有的數(shù)組elementData對象的指定下標(biāo)處,賦值為null,GC會刪除沒有Root結(jié)點(diǎn)對象連接的對象

8、向調(diào)用者返回刪除后的元素

return會返回此時被刪除的元素對象

remove(Object)方法分析

    public boolean remove(Object o) {
        return removeElement(o);
    }

用于將第一個匹配的元素對象刪除的方法,傳入的參數(shù)為元素對象,此方法并沒有使用synchronized修飾,那么它如何保證線程安全的刪除元素呢?往下看……

1、實際調(diào)用removeElement()方法

2、向調(diào)用者返回刪除結(jié)果

removeElement(Object)方法分析

    public synchronized boolean removeElement(Object obj) {
        modCount++;
        int i = indexOf(obj);
        if (i >= 0) {
            removeElementAt(i);
            return true;
        }
        return false;
    }

用于刪除元素的方法,使用synchronized修飾,同一時刻只有獲得對象鎖的線程可以執(zhí)行該方法,未獲得對象鎖的線程,將被阻塞在方法的入口處,傳入的1個參數(shù)表示元素對象

1、fail-fast機(jī)制保護(hù)

modCount增加1,表示Vector持有的元素發(fā)生改變

2、獲取元素對象在數(shù)組中的下標(biāo)

調(diào)用index()方法,同時會將元素對象ob傳入進(jìn)去,返回值則由局部變量i負(fù)責(zé)存儲,它存儲的是元素在數(shù)組中下標(biāo)

3、元素存在,則繼續(xù)執(zhí)行刪除工作

當(dāng)局部變量i的值大于等于0,說明元素存儲在數(shù)組中(Vector對象持有一個數(shù)組對象,用于保存元素的引用),通過調(diào)用removeElement()方法完成刪除工作,最后向調(diào)用者返回true,表示刪除元素成功

4、當(dāng)元素不存在時,向調(diào)用者返回false

removeElementAt(int)方法分析

    public synchronized void removeElementAt(int index) {
        modCount++;
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                     elementCount);
        }
        else if (index < 0) {
            throw new ArrayIndexOutOfBoundsException(index);
        }
        int j = elementCount - index - 1;
        if (j > 0) {
            System.arraycopy(elementData, index + 1, elementData, index, j);
        }
        elementCount--;
        elementData[elementCount] = null; /* to let gc do its work */
    }

用于刪除指定下標(biāo)的元素,使用synchronized修飾,同一時刻只有1個線程可以執(zhí)行該方法,其它未獲得對象鎖的線程將被阻塞在入口處,傳入的1個參數(shù)index表示元素的下標(biāo)

1、fail-fast機(jī)制

modCount增加1,表示Vector保存的元素發(fā)生改變

2、檢查下標(biāo)是否合理

當(dāng)傳入的下標(biāo)index大于等于Vector對象持有的elementCount值時,拋出ArrayIndexOutOfBoundsException,告知調(diào)用者,index >= xx值

當(dāng)傳入的下標(biāo)index小于0時,同樣拋出ArrayIndexOutOfBoundsException對象,此時只告知index值是多少

只有下標(biāo)0至elementCount - 1的范圍內(nèi),才有元素,所以作者的保護(hù)相當(dāng)?shù)暮侠?/p>

3、計算需要移動元素的數(shù)量

比如一共保存了5個元素(elementCount)、需要刪除下標(biāo)為3的元素,下標(biāo)為3的元素是第4個元素,后續(xù)需要挪動的元素數(shù)量為1,所以

公式為:remove_num = elementCount - index - 1,我們再套進(jìn)來公式里:remove_num = 5 - 3 - 1

4、開始挪動元素

挪動元素,而采用的是復(fù)制元素,system類的靜態(tài)方法arrycopy即可做到,它接受5個參數(shù)

第一個參數(shù):表示需要從哪個數(shù)組對象中復(fù)制元素(源頭)

第二個參數(shù):表示需要從數(shù)組對象的哪個下標(biāo)處,開始復(fù)制

第三個參數(shù):表示需要粘貼到哪個數(shù)組對象中(目標(biāo))

第四個參數(shù):表示需要粘貼到數(shù)組對象的起始下標(biāo)

第五個參數(shù):表示共計復(fù)制幾個元素

5、記錄的元素總數(shù)減去1

elementCount減少1

6、將剩下的數(shù)組中,多余的引用,刪除掉

因為每個元素都向前復(fù)制了一位,所以此時的elementCount指向的下標(biāo)處,還存著對象的引用,這會造成對象無法被GC回收,賦值為null,由GC回收對象占用的內(nèi)存空間

removeIf()方法分析

    public synchronized boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        // figure out which elements are to be removed
        // any exception thrown from the filter predicate at this stage
        // will leave the collection unmodified
        int removeCount = 0;
        final int size = elementCount;
        final BitSet removeSet = new BitSet(size);
        final int expectedModCount = modCount;
        for (int i=0; modCount == expectedModCount && i < size; i++) {
            @SuppressWarnings("unchecked")
            final E element = (E) elementData[i];
            if (filter.test(element)) {
                removeSet.set(i);
                removeCount++;
            }
        }
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
 
        // shift surviving elements left over the spaces left by removed elements
        final boolean anyToRemove = removeCount > 0;
        if (anyToRemove) {
            final int newSize = size - removeCount;
            for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
                i = removeSet.nextClearBit(i);
                elementData[j] = elementData[i];
            }
            for (int k=newSize; k < size; k++) {
                elementData[k] = null;  // Let gc do its work
            }
            elementCount = newSize;
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
            modCount++;
        }
        return anyToRemove;
    }

實現(xiàn)Collection接口的方法,用于根據(jù)指定條件刪除元素的方法,同樣由synchronized修飾,同一時刻只有獲取到當(dāng)前對象鎖的線程可以調(diào)用此方法,其它線程如果也調(diào)用此方法,會被阻塞在方法的入口處

1、檢查傳入的Predicate對象

確保Predicate對象必須傳入,此處使用Objects的靜態(tài)方法requireNonNull()檢查

2、創(chuàng)建用于記錄刪除數(shù)量的局部變量

removeCount,默認(rèn)值為0

3、臨時存儲當(dāng)前Vector對象持有的元素總數(shù)

創(chuàng)建一個局部變量size用于存儲當(dāng)前元素總數(shù)elementCount

4、創(chuàng)建BitSet對象

利用Vector對象持有的元素總數(shù)size,用于創(chuàng)建一個BitSet對象,局部變量removeSet臨時指向該此BitSet對象

removeAllElement()方法分析

    public synchronized void removeAllElements() {
        modCount++;
        // Let gc do its work
        for (int i = 0; i < elementCount; i++)
            elementData[i] = null;
         elementCount = 0;
    }

用于刪除Vector對象持有的所有元素對象

1、fail-fast機(jī)制保護(hù)

實例變量modCount增加1,表示Vector持有的元素發(fā)生變化

2、遍歷數(shù)組對象

將Vector對象持有的數(shù)組對象elementData中實際保存元素對象引用的所有位置,全部賦值為null,當(dāng)對象從GC Roots處不可達(dá)時,垃圾收集器會回收對象占用的內(nèi)存空間

3、元素總數(shù)標(biāo)記為0

Vector對象持有的elementCount標(biāo)記為0,說明Vector對象不再持有任何元素 

removeAll(Collection)方法分析

    public synchronized boolean removeAll(Collection<?> c) {
        return super.removeAll(c);
    }

用于刪除多個元素的方法,只有與傳入的Collection對象中持有的元素匹配的元素會被刪除

1、直接調(diào)用父類的removeAll()方法,并將傳入的Collection對象傳入進(jìn)去

2、向調(diào)用者返回刪除元素的結(jié)果

父類中的removeAll(Collection)方法分析

    public boolean removeAll(Collection<?> c) {
        Objects.requireNonNull(c);
        boolean modified = false;
        Iterator<?> it = iterator();
        while (it.hasNext()) {
            if (c.contains(it.next())) {
                it.remove();
                modified = true;
            }
        }
        return modified;
    }

位于父類AbstractCollection中,用于刪除與傳入?yún)?shù)Collection對象中匹配的所有元素

1、檢查傳入?yún)?shù)Collection對象

2、定義局部變量,表示是否修改,默認(rèn)值false

3、調(diào)用iterator()方法獲取迭代器對象,并由局部變量it負(fù)責(zé)保存

此iterator()方法都是子類去實現(xiàn),Vector中也實現(xiàn)了該方法,此方法會返回一個迭代器對象

4、使用迭代器對象的方法進(jìn)行遍歷與刪除

hasNext()方法用于判斷是否有下一個元素,當(dāng)?shù)谝淮问褂脮r,判斷的是第一個元素

next()方法可以獲取到一個元素,第一次使用時,獲取到的是第一個元素

remove()方法可以刪除一個元素

每當(dāng)刪除一個元素(Vector中持有的元素與Collection中的某個元素相同),將是否修改的標(biāo)志位modified賦值為true

5、向調(diào)用者返回刪除結(jié)果 

retainAll(Collection)方法分析

    public synchronized boolean retainAll(Collection<?> c) {
        return super.retainAll(c);
    }

用于刪除除了傳入的Collection對象持有的元素之外的所有元素,求交集……

總結(jié)

1、即可以刪除一個元素、也可以刪除多個元素

2、fail-fast機(jī)制除了保護(hù)多線程下的使用,也防止在單線程下即遍歷、又刪除

3、為了規(guī)避一邊遍歷,一邊刪除的鍋,可以使用迭代器對象提供的一邊遍歷、一邊刪除的方法

以上就是基于java構(gòu)造方法Vector刪除元素源碼分析的詳細(xì)內(nèi)容,更多關(guān)于java構(gòu)造方法Vector的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java內(nèi)部排序之插入排序與交換排序詳解

    Java內(nèi)部排序之插入排序與交換排序詳解

    這篇文章主要介紹了Java內(nèi)部排序之插入排序與交換排序詳解,排序是將任意序列重新排列按照關(guān)鍵字有序,排序根基存儲器的不同分為內(nèi)部排序、外部排序,排序根據(jù)關(guān)鍵字分為穩(wěn)定排序、不穩(wěn)定排序,需要的朋友可以參考下
    2023-12-12
  • struts2如何使用攔截器進(jìn)行用戶權(quán)限控制實例

    struts2如何使用攔截器進(jìn)行用戶權(quán)限控制實例

    本篇文章主要介紹了struts2如何使用攔截器進(jìn)行用戶權(quán)限控制實例,非常具有實用價值,需要的朋友可以參考下
    2017-05-05
  • springboot中請求地址轉(zhuǎn)發(fā)的兩種方案

    springboot中請求地址轉(zhuǎn)發(fā)的兩種方案

    在開發(fā)過程中,我們經(jīng)常需要將請求從一個服務(wù)轉(zhuǎn)發(fā)到另一個服務(wù),以實現(xiàn)不同服務(wù)之間的協(xié)作,本文主要介紹了springboot中請求地址轉(zhuǎn)發(fā)的兩種方案,感興趣的可以了解一下
    2023-11-11
  • Java面試題沖刺第二十九天--JVM3

    Java面試題沖刺第二十九天--JVM3

    這篇文章主要為大家分享了最有價值的三道關(guān)于JVM的面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Java中equals和==的區(qū)別詳解

    Java中equals和==的區(qū)別詳解

    這篇文章主要介紹了詳解 Java 中 equals 和 == 的區(qū)別的相關(guān)資料,equals 和 == 都是用來檢測兩個字符串是否相等,返回值也都是布爾型,但是兩者在內(nèi)部比較的處理中卻不盡相同需要的朋友可以參考下
    2021-09-09
  • Java結(jié)合redistemplate使用分布式鎖案例講解

    Java結(jié)合redistemplate使用分布式鎖案例講解

    在Java中使用RedisTemplate結(jié)合Redis來實現(xiàn)分布式鎖是一種常見的做法,特別適用于微服務(wù)架構(gòu)或多實例部署的應(yīng)用程序中,以確保數(shù)據(jù)的一致性和避免競態(tài)條件,下面給大家分享使用Spring Boot和RedisTemplate實現(xiàn)分布式鎖的案例,感興趣的朋友一起看看吧
    2024-08-08
  • Intellij IDEA 關(guān)閉和開啟自動更新的提示?

    Intellij IDEA 關(guān)閉和開啟自動更新的提示?

    這篇文章主要介紹了Intellij IDEA 關(guān)閉和開啟自動更新的提示操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • mybatis如何返回某列的最大值

    mybatis如何返回某列的最大值

    這篇文章主要介紹了mybatis如何返回某列的最大值操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 編譯大型Java項目class沖突導(dǎo)致報錯的解決方案

    編譯大型Java項目class沖突導(dǎo)致報錯的解決方案

    這篇文章給大家盤點(diǎn)編譯大型項目class沖突導(dǎo)致報錯的解決方案,文中通過代碼示例介紹的非常詳細(xì),具有一定的參考價值,需要的朋友可以參考下
    2023-10-10
  • 詳解Java線程池隊列中的延遲隊列DelayQueue

    詳解Java線程池隊列中的延遲隊列DelayQueue

    這篇文章主要為大家詳細(xì)介紹了Java線程池隊列中的延遲隊列DelayQueue的相關(guān)資料,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-12-12

最新評論

酉阳| 抚松县| 松阳县| 绥江县| 永善县| 沾益县| 富民县| 白河县| 温泉县| 雅江县| 方城县| 义乌市| 元朗区| 贵港市| 定远县| 兰州市| 隆安县| 永泰县| 北辰区| 五华县| 城市| 廉江市| 交城县| 凤庆县| 利津县| 久治县| 龙山县| 苗栗市| 茶陵县| 新平| 宜春市| 永年县| 胶南市| 沐川县| 青铜峡市| 淮滨县| 札达县| 涡阳县| 陆河县| 大英县| 永靖县|