數(shù)據(jù)結(jié)構(gòu)ArrayList、LinkedList芳撒、Vector等

ArrayList:底層是數(shù)組邓深,初始容量是10未桥,若存入數(shù)量達(dá)到11即觸發(fā)擴(kuò)容方法,容量擴(kuò)容百分之50芥备。?

??? int newCapacity =oldCapacity + (oldCapacity >> 1);

????elementData = Arrays.copyOf(elementData, newCapacity);

每次調(diào)用add或remove方法冬耿,modCount都會(huì)加一,這個(gè)值會(huì)在checkForComodification方法中作為判斷條件決定是否拋出異常萌壳。

LinkedList:底層是繼承AbstractSequentialList的雙向循環(huán)鏈表亦镶。它也可以被當(dāng)作堆棧、隊(duì)列或雙端隊(duì)列進(jìn)行操作袱瓮,每次調(diào)用add方法都是添加至尾部缤骨,無(wú)論LInkedList大小,每次添加所需時(shí)間都是固定的(只需開辟最后一個(gè)節(jié)點(diǎn)的空間尺借,塞值)绊起,

在刪除可插入對(duì)象的動(dòng)作時(shí),為什么ArrayList的效率會(huì)比較低呢?

解析:因?yàn)锳rrayList是使用數(shù)組實(shí)現(xiàn)的,若要從數(shù)組中刪除或插入某一個(gè)對(duì)象燎斩,需要移動(dòng)后段的數(shù)組元素虱歪,從而會(huì)重新調(diào)整索引順序,調(diào)整索引順序會(huì)消耗一定的時(shí)間,所以速度上就會(huì)比LinkedList要慢許多. 相反,LinkedList是使用鏈表實(shí)現(xiàn)的,若要從鏈表中刪除或插入某一個(gè)對(duì)象,只需要改變前后對(duì)象的引用即可!

Vector:底層是對(duì)象數(shù)組栅表,初始容量是10笋鄙,擴(kuò)容百分之百。

int newCapacity

= oldCapacity + ((capacityIncrement > 0) ?capacityIncrement : oldCapacity);

底層方法都用synchronized方法保證并發(fā)安全谨读。所以效率低局装。且調(diào)用remove方法時(shí),??? 不會(huì)調(diào)節(jié)底層數(shù)組大小劳殖。

Vector擴(kuò)展:Vector所有方法都上鎖铐尚,單個(gè)方法被調(diào)用是都是線程安全的,但是對(duì)它的復(fù)合操作無(wú)法保證其線程安全哆姻。

例如定義該方法:public Object deleteLast(Vector v){

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int lastIndex?= v.size()-1;

??????????????????????????????????????????????????????? v.remove(lastIndex);

????????????????????????????????}

Remove源碼:public synchronized E remove(int index) {

??????????????????????????????????????????????????????? ?modCount++;

??????????????????????????????????????????????????????? ?if (index >= elementCount)

????????????????????????????????????????? ?? throw newArrayIndexOutOfBoundsException(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 gcdo its work

??????????????????????????????????????????????????????? ?return oldValue;

}

Size和remove方法都是線程安全的宣增,但在該deleteLast方法中,多線程操作可能會(huì)拋??????????? 出異常矛缨。AB線程同時(shí)進(jìn)入????????????? deleteLast方法內(nèi)爹脾,A方法執(zhí)行到了remove,B方法執(zhí)行到????????????? size箕昭,A先刪除灵妨,B就拋異常。

CopyOnWriteArrayList:實(shí)現(xiàn)了List落竹、RandomAccess接口泌霍,底層使用ReentrantLock支持并發(fā)操作,調(diào)用add?????? 方法時(shí)述召,上鎖后朱转,獲得當(dāng)前數(shù)組蟹地,數(shù)組擴(kuò)容+1,新數(shù)組插入數(shù)據(jù)后將數(shù)組引用指向新數(shù)???????? 組藤为,釋放鎖怪与。另一個(gè)add(index,value)方法,在插入值時(shí)缅疟,先判斷該Index是否有效且位????? 置上沒(méi)存值分别,若沒(méi)存則重復(fù)上述劃線操作;若有值窿吩,則

? ? ? ? ? ? ? ?newElements = new Object[len + 1];

??????????????? System.arraycopy(elements, 0,newElements, 0, index);

??????????????? System.arraycopy(elements,index, newElements, index + 1,numMoved);

刪除方法與上述斜體字操作類似茎杂,若index位置在末尾則直接縮減數(shù)組大小错览,否則

? ? ? ? ? ? ? Object[] newElements = new Object[len - 1];

??????????????? System.arraycopy(elements, 0,newElements, 0, index);

??????????????? System.arraycopy(elements,index + 1, newElements, index,numMoved);

??????????????? setArray(newElements);

LinkedList以及ArrayList的迭代效率比較

ArrayList實(shí)現(xiàn)了RandomAccess接口纫雁,LinkedList沒(méi)有實(shí)現(xiàn)。

實(shí)現(xiàn)RandomAccess接口的意思:http://www.jb51.net/article/92127.htm

結(jié)論:ArrayList使用最普通的for循環(huán)遍歷最快倾哺,LinkedList使用foreach循環(huán)較為??? 快(*LinkedList使用foreach遍歷巨慢轧邪,foreach底層調(diào)用Iterator遍歷*)

如果集合類是RandomAccess的實(shí)現(xiàn),則盡量用for(int i = 0; i < size; i++) 來(lái)遍歷而不要用Iterator迭代器來(lái)遍歷羞海。

反過(guò)來(lái)忌愚,如果List是Sequence List,則最好用迭代器來(lái)進(jìn)行迭代却邓。

JDK中說(shuō)的很清楚硕糊,在對(duì)List特別是Huge size的List的遍歷算法中,要盡量來(lái)判斷是屬于RandomAccess(如ArrayList)還是Sequence List (如LinkedList)腊徙,因?yàn)檫m合RandomAccess List的遍歷算法简十,用在Sequence List上就差別很大

Vector和ArrayList的區(qū)別

實(shí)現(xiàn)原理都是通過(guò)數(shù)組實(shí)現(xiàn),查詢速度快撬腾,增加螟蝙、刪除、修改速度慢民傻,區(qū)別在于vector是線程安全的胰默,ArrayList是線程不安全的,但是效率高漓踢。

ArrayList 和 LinkedList區(qū)別

1.? ? ? 隨機(jī)訪問(wèn)get和set牵署,ArrayList速度優(yōu)于LinkedList,因?yàn)長(zhǎng)inkedList需要移動(dòng)指針?????

2.????? 對(duì)于add 和 remove操作喧半,LinkedList速度優(yōu)于ArrayList奴迅,因?yàn)锳rrayList需要移動(dòng)數(shù)據(jù)

CopyOnWriteArrayList和 ArrayList的區(qū)別

1.? ? ? ? 每次調(diào)用remove 和 add方法都會(huì)對(duì)modCount加1,這個(gè)值會(huì)在checkForComodification方法中作為判斷條件決定是否拋出異常薯酝。

2.? ? ? ? CopyOnWriteArrayList代碼底層有重入鎖半沽,可以支持并發(fā)爽柒,它每次改動(dòng)都會(huì)拷貝一個(gè)副本數(shù)組,在副本數(shù)組操作后者填,改變引用指向副本數(shù)組浩村。

3.? ? ? ? CopyOnWriteArrayList的缺點(diǎn)就是每個(gè)線程操作它都需要拷貝一個(gè)副本數(shù)組,?? 如果副本數(shù)組比較大則會(huì)占用大內(nèi)存占哟,造成多次垃圾回收心墅。

假如多個(gè)線程一起操作CopyOnWriteArrayList,一個(gè)線程修改榨乎,一個(gè)線程讀取怎燥,則讀取到舊數(shù)據(jù),所以CopyOnWriteArrayList只能保證最終的一致性蜜暑,不能保證實(shí)時(shí)一致性铐姚。它適用于讀操作遠(yuǎn)多于寫操作的處理,例如緩存肛捍。

HashMap和HashTable的區(qū)別:

1.HashMap不是線程安全的 HastMap是一個(gè)接口 是map接口的子接口隐绵,是將鍵映射到值的對(duì)象,其中鍵和值都是對(duì)象拙毫,并且不能包含重復(fù)鍵依许,但可以包含重復(fù)值。HashMap允許null key和null value缀蹄,而hashtable不允許峭跳。

2.HashTable是線程安全的一個(gè)Collection。

3.HashMap是Hashtable的輕量級(jí)實(shí)現(xiàn)(非線程安全的實(shí)現(xiàn))缺前,他們都完成了Map接口蛀醉,主要區(qū)別在于HashMap允許空(null)鍵值(key),由于非線程安全,效率上可能高于Hashtable诡延。

HashMap允許將null作為一個(gè)entry的key或者value滞欠,而Hashtable不允許。

HashMap把Hashtable的contains方法去掉了肆良,改成containsvalue和containsKey筛璧。

a)? ? ?HashMap底層是由數(shù)組+鏈表+紅黑樹構(gòu)成。默認(rèn)容量是16惹恃,加載因子是0.75夭谤,鏈表轉(zhuǎn)紅黑樹的閾值是8。初始化HashMap有三種方法(無(wú)參巫糙,帶初始容量朗儒,帶初始容量及加載因子),其中后兩種運(yùn)用了門面模式(其實(shí)是一個(gè)方法),put值的時(shí)候先判斷是否需要調(diào)用resize方法擴(kuò)容.若resize后需要rehash重新計(jì)算Key對(duì)應(yīng)的值(位置)再進(jìn)行插入醉锄。HashMap的時(shí)間復(fù)雜度是O(n).允許存null

b)????? HashTable底層數(shù)組+鏈表乏悄。默認(rèn)容量11,加載因子是0.75.初始化HashTable有三種方法(無(wú)參恳不,帶初始容量檩小,帶初始容量及加載因子),后兩種也運(yùn)用了門面模式烟勋,put值得時(shí)候先計(jì)算key的hash對(duì)應(yīng)的Index规求,然后遍歷該節(jié)點(diǎn)位置的值,若key相同則替換舊值卵惦,否則新開辟一個(gè)Entry存放key value.HashTable所有方法都帶有synchronized,不支持存null.

c)????? ConcurrentHashMap底層是數(shù)組+鏈表+紅黑樹阻肿。默認(rèn)容量16,加載因子0.75沮尿,鏈表轉(zhuǎn)紅黑樹的閾值是8,丛塌。初始化ConcurrentHashMap有四種方法(無(wú)參,帶初始容量蛹找,帶初始容量及加載因子姨伤,帶Map)。ConcurrentHashMap不支持存null,put值得時(shí)候先判斷table是否為空庸疾,否則初始化table,然后計(jì)算key的hash后的Index,若該位置為空則直接新加節(jié)點(diǎn)存且過(guò)程不上鎖当编。若該位置有值則上分段鎖保證并發(fā)安全届慈。(HashTable縮小版)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市忿偷,隨后出現(xiàn)的幾起案子金顿,更是在濱河造成了極大的恐慌,老刑警劉巖鲤桥,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件揍拆,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡茶凳,警方通過(guò)查閱死者的電腦和手機(jī)嫂拴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)贮喧,“玉大人筒狠,你說(shuō)我怎么就攤上這事∠渎伲” “怎么了辩恼?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我灶伊,道長(zhǎng)疆前,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任聘萨,我火速辦了婚禮峡继,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘匈挖。我一直安慰自己碾牌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布儡循。 她就那樣靜靜地躺著舶吗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪择膝。 梳的紋絲不亂的頭發(fā)上誓琼,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音肴捉,去河邊找鬼腹侣。 笑死,一個(gè)胖子當(dāng)著我的面吹牛齿穗,可吹牛的內(nèi)容都是我干的傲隶。 我是一名探鬼主播,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼窃页,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼跺株!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起脖卖,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤乒省,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后畦木,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體袖扛,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年十籍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蛆封。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡妓雾,死狀恐怖娶吞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情械姻,我是刑警寧澤妒蛇,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布机断,位于F島的核電站,受9級(jí)特大地震影響绣夺,放射性物質(zhì)發(fā)生泄漏吏奸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一陶耍、第九天 我趴在偏房一處隱蔽的房頂上張望奋蔚。 院中可真熱鬧,春花似錦烈钞、人聲如沸泊碑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)馒过。三九已至,卻和暖如春酗钞,著一層夾襖步出監(jiān)牢的瞬間腹忽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工砚作, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留窘奏,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓葫录,卻偏偏與公主長(zhǎng)得像着裹,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子压昼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容