国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java容器類研究3:AbstractCollection

Donald / 3485人閱讀

摘要:隨機(jī)訪問數(shù)據(jù)是相對(duì)于順序訪問數(shù)據(jù)而言,例如鏈表的形式。方法將容器中的元素轉(zhuǎn)化為數(shù)組的形式。在函數(shù)中,對(duì)容量每次擴(kuò)展的大小,并且會(huì)檢查是否會(huì)超過設(shè)定的最大數(shù)組長度。如果長度超過了限定值,則以原容量為底線,返回一個(gè)最大容量。

ArrayList繼承自AbstractList,AbstractList為“random access”的數(shù)組提供了基本的實(shí)現(xiàn)。隨機(jī)訪問數(shù)據(jù)是相對(duì)于順序訪問數(shù)據(jù)而言,例如鏈表的形式。AbstractSequentialList為鏈表形式的順序訪問提供了基本實(shí)現(xiàn)。AbstractList提供了默認(rèn)的隨機(jī)訪問數(shù)據(jù)的iterator。AbstractList繼承自AbstractCollection,AbstractCollection為Collection提供了基本實(shí)現(xiàn)。

java.util.AbstractCollection

contains

AbstractCollection實(shí)現(xiàn)了查詢是否包含某一個(gè)元素的方法。最好使用Iterator遍歷集合中的元素,因?yàn)榭梢云帘渭蟽?nèi)部元素存儲(chǔ)的具體實(shí)現(xiàn),并且根據(jù)不同的數(shù)據(jù)存儲(chǔ)特點(diǎn),優(yōu)化訪問策略。這里還可以正確查找null元素,需要注意的是對(duì)null元素的查詢需要特別的處理,有時(shí)候自己實(shí)現(xiàn)方法時(shí),往往會(huì)忽略傳入?yún)?shù)為null時(shí)的處理,導(dǎo)致方法無法處理特殊情況。

    public boolean contains(Object o) {
        Iterator it = iterator();
        if (o==null) {
            while (it.hasNext())
                if (it.next()==null)
                    return true;
        } else {
            while (it.hasNext())
                if (o.equals(it.next()))
                    return true;
        }
        return false;
    }
toArray

toArray方法將容器中的元素轉(zhuǎn)化為數(shù)組的形式。這里元素的復(fù)制,采用的是直接復(fù)制引用。這里還考慮到了并發(fā)運(yùn)算時(shí),元素?cái)?shù)量在復(fù)制時(shí)產(chǎn)生變化的情況,當(dāng)數(shù)量減少時(shí),就用Arrays.copy()截取結(jié)果。當(dāng)數(shù)量增加時(shí),會(huì)調(diào)用finishToArray函數(shù)擴(kuò)容。

    public Object[] toArray() {
        // Estimate size of array; be prepared to see more or fewer elements
        Object[] r = new Object[size()];
        Iterator it = iterator();
        for (int i = 0; i < r.length; i++) {
            if (! it.hasNext()) // fewer elements than expected
                return Arrays.copyOf(r, i);
            r[i] = it.next();
        }
        return it.hasNext() ? finishToArray(r, it) : r;
    }

在finishToArray函數(shù)中,對(duì)容量每次擴(kuò)展1/2+1的大小,并且會(huì)檢查是否會(huì)超過設(shè)定的最大數(shù)組長度MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8。如果長度超過了限定值,則以原容量+1為底線,返回一個(gè)最大容量。最后返回的數(shù)組也會(huì)修剪掉多余的位置。

    private static  T[] finishToArray(T[] r, Iterator it) {
        int i = r.length;
        while (it.hasNext()) {
            int cap = r.length;
            if (i == cap) {
                int newCap = cap + (cap >> 1) + 1;
                // overflow-conscious code
                if (newCap - MAX_ARRAY_SIZE > 0)
                    newCap = hugeCapacity(cap + 1);
                r = Arrays.copyOf(r, newCap);
            }
            r[i++] = (T)it.next();
        }
        // trim if overallocated
        return (i == r.length) ? r : Arrays.copyOf(r, i);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError
                ("Required array size too large");
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

這里有一個(gè)toArray的重載,需要傳入一個(gè)數(shù)組作為參數(shù),據(jù)我觀察,目的是將集合中的元素存入指定的數(shù)組,重利用已有數(shù)組的存儲(chǔ)。如果元素過多,而目標(biāo)數(shù)組容納不下,只能重新申請(qǐng)數(shù)組來進(jìn)行存儲(chǔ)。

    public  T[] toArray(T[] a) {
        // Estimate size of array; be prepared to see more or fewer elements
        int size = size();
        T[] r = a.length >= size ? a :
                  (T[])java.lang.reflect.Array
                  .newInstance(a.getClass().getComponentType(), size);
        Iterator it = iterator();

        for (int i = 0; i < r.length; i++) {
            if (! it.hasNext()) { // fewer elements than expected
                if (a == r) {
                    //利用的原數(shù)組,且元素不足,則補(bǔ)null表示結(jié)束
                    r[i] = null; // null-terminate
                } else if (a.length < i) {
                    //元素較少,但數(shù)量超過原始數(shù)組,只能用新數(shù)組
                    return Arrays.copyOf(r, i);
                } else {
                    //元素減少,導(dǎo)致原始數(shù)組可以容納下,則copy回原始數(shù)組,折騰唄
                    System.arraycopy(r, 0, a, 0, i);
                    if (a.length > i) {
                        a[i] = null;
                    }
                }
                return a;
            }
            r[i] = (T)it.next();
        }
        // more elements than expected
        return it.hasNext() ? finishToArray(r, it) : r;
    }
removeAll

removeAll方法刪除目標(biāo)集合中的所有重疊元素。Iterator可以做到在遍歷時(shí),安全的刪除元素,而通過index循環(huán)刪除則可能導(dǎo)致index偏移。

    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;
    }
toString

AbstractCollection的toString實(shí)現(xiàn),比較令我震驚的是e == this的作用。這里為什么要判斷打印的內(nèi)容是否為自己本身?因?yàn)?b>sb.append(e == this ? "(this Collection)" : e);會(huì)調(diào)用e的toString函數(shù)來生成字符串,若不加判斷,則會(huì)形成無限的toString遞歸調(diào)用。我猜想一下,估計(jì)當(dāng)時(shí)toString的實(shí)現(xiàn)者沒有注意到該問題的存在,直到該bug出現(xiàn),腦洞不大還真難想起來這個(gè)問題。

    public String toString() {
        Iterator it = iterator();
        if (! it.hasNext())
            return "[]";

        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (;;) {
            E e = it.next();
            sb.append(e == this ? "(this Collection)" : e);
            if (! it.hasNext())
                return sb.append("]").toString();
            sb.append(",").append(" ");
        }
    }

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/67735.html

相關(guān)文章

  • 通過面試題,讓我們來了解Collection

    摘要:說一說迭代器通過集合對(duì)象獲取其對(duì)應(yīng)的對(duì)象判斷是否存在下一個(gè)元素取出該元素并將迭代器對(duì)象指向下一個(gè)元素取出元素的方式迭代器。對(duì)于使用容器者而言,具體的實(shí)現(xiàn)不重要,只要通過容器獲取到該實(shí)現(xiàn)的迭代器的對(duì)象即可,也就是方法。 前言 歡迎關(guān)注微信公眾號(hào):Coder編程獲取最新原創(chuàng)技術(shù)文章和相關(guān)免費(fèi)學(xué)習(xí)資料,隨時(shí)隨地學(xué)習(xí)技術(shù)知識(shí)!** 本章主要介紹Collection集合相關(guān)知識(shí),結(jié)合面試中會(huì)提到...

    HelKyle 評(píng)論0 收藏0
  • 容器之Collection、Iterable、List、Vector(Stack)分析(三)

    摘要:容器相關(guān)的操作及其源碼分析說明本文是基于分析的。通常,我們通過迭代器來遍歷集合。是接口所特有的,在接口中,通過返回一個(gè)對(duì)象。為了偷懶啊,底層使用了迭代器。即返回的和原在元素上保持一致,但不可修改。 容器相關(guān)的操作及其源碼分析 說明 1、本文是基于JDK 7 分析的。JDK 8 待我工作了得好好研究下。Lambda、Stream。 2、本文會(huì)貼出大量的官方注釋文檔,強(qiáng)迫自己學(xué)英語,篇幅...

    liaosilzu2007 評(píng)論0 收藏0
  • 說一說java.util.Arrays$ArrayList

    摘要:值得注意的是,的迭代器是否要調(diào)用方法是由要?jiǎng)h除的目標(biāo)是否數(shù)組的元素決定的,如果不存在這樣的元素,則下面的代碼并不會(huì)出現(xiàn)異常, java.util.Arrays$ArrayList(下文:Arrays$ArrayList)是java.util.Arrays的私有靜態(tài)內(nèi)部類,他實(shí)現(xiàn)的接口,繼承的父類幾乎和java.util.ArrayList(下文:ArrayList)相同,既然是私有的,...

    linkin 評(píng)論0 收藏0
  • Java筆記-容器源碼(持續(xù)更新)

    摘要:加載因子是哈希表在其容量自動(dòng)增加之前可以達(dá)到多滿的一種尺度。當(dāng)哈希表中的條目數(shù)超出了加載因子與當(dāng)前容量的乘積時(shí),則要對(duì)該哈希表進(jìn)行操作即重建內(nèi)部數(shù)據(jù)結(jié)構(gòu),從而哈希表將具有大約兩倍的桶數(shù)。成員變量每個(gè)對(duì)由封裝,存在了對(duì)象數(shù)組中。 雖是讀書筆記,但是如轉(zhuǎn)載請(qǐng)注明出處 http://segmentfault.com/blog/exploring/ .. 拒絕伸手復(fù)制黨 LinkedLis...

    mrli2016 評(píng)論0 收藏0
  • 淺析guava容器multimap

    摘要:它主要做了件事初始化容器,并將元素添加到容器里維護(hù)這樣我們?cè)僬{(diào)用的方法直接就返回了,不需要再次遍歷和統(tǒng)計(jì)的過程。維護(hù)實(shí)時(shí)的維護(hù),及時(shí)刪除總結(jié)整體上是對(duì)底層的二次封裝,很好的處理了各種細(xì)節(jié),比如子容器的判空處理,的計(jì)算效率,的維護(hù)等。 在日常開發(fā)中我們通常有需要對(duì) List 容器進(jìn)行分組的情況,比如對(duì)下面的list數(shù)據(jù)根據(jù)name字段來進(jìn)行分組: [ { date...

    yy13818512006 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<