ArrayList,LinkedList,Vector這三個(gè)類都實(shí)現(xiàn)了java.util.List接口鼻忠,但它們有各自不同的特性,主要如下:
一开缎、同步性
ArrayList,LinkedList都是線程不同步的裸卫,而Vector是線程同步的哗蜈。所以如果不要求線程安全的話协怒,可以使用ArrayList或LinkedList涝焙,可以節(jié)省為同步而耗費(fèi)的開(kāi)銷。但在多線程的情況下孕暇,有時(shí)候就不得不使用Vector了仑撞。當(dāng)然,也可以通過(guò)一些辦法包裝ArrayList,LinkedList妖滔,使他們也達(dá)到同步隧哮,但效率可能會(huì)有所降低。
二座舍、數(shù)據(jù)增長(zhǎng)
從內(nèi)部實(shí)現(xiàn)機(jī)制來(lái)講ArrayList和Vector都是使用Objec的數(shù)組形式來(lái)存儲(chǔ)的沮翔。當(dāng)你向這兩種類型中增加元素的時(shí)候,如果元素的數(shù)目超出了內(nèi)部數(shù)組目前的長(zhǎng)度它們都需要擴(kuò)展內(nèi)部數(shù)組的長(zhǎng)度簸州,Vector缺省情況下自動(dòng)增長(zhǎng)原來(lái)一倍的數(shù)組長(zhǎng)度鉴竭,ArrayList是原來(lái)的50%,所以最后你獲得的這個(gè)集合所占的空間總是比你實(shí)際需要的要大歧譬。所以如果你要在集合中保存大量的數(shù)據(jù)那么使用Vector有一些優(yōu)勢(shì)岸浑,因?yàn)槟憧梢酝ㄟ^(guò)設(shè)置集合的初始化大小來(lái)避免不必要的資源開(kāi)銷搏存。
三、檢索矢洲、插入璧眠、刪除對(duì)象的效率
ArrayList和Vector中,從指定的位置(用index)檢索一個(gè)對(duì)象读虏,或在集合的末尾插入责静、刪除一個(gè)對(duì)象的時(shí)間是一樣的,可表示為O(1)盖桥。但是灾螃,如果在集合的其他位置增加或移除元素那么花費(fèi)的時(shí)間會(huì)呈線形增長(zhǎng):O(n-i),其中n代表集合中元素的個(gè)數(shù)揩徊,i代表元素增加或移除元素的索引位置腰鬼。為什么會(huì)這樣呢?以為在進(jìn)行上述操作的時(shí)候集合中第i和第i個(gè)元素之后的所有元素都要執(zhí)行(n-i)個(gè)對(duì)象的位移操作塑荒。
LinkedList中熄赡,在插入、刪除集合中任何位置的元素所花費(fèi)的時(shí)間都是一樣的—O(1)齿税,但它在索引一個(gè)元素的時(shí)候比較慢彼硫,為O(i),其中i是索引的位置。
————————————————————————————————————————-------------------------------------------------------------------------------
一般大家都知道ArrayList和LinkedList的大致區(qū)別:
1.ArrayList是實(shí)現(xiàn)了基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu)凌箕,LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu)拧篮。
2.對(duì)于隨機(jī)訪問(wèn)get和set,ArrayList覺(jué)得優(yōu)于LinkedList牵舱,因?yàn)長(zhǎng)inkedList要移動(dòng)指針他托。
3.對(duì)于新增和刪除操作add和remove,LinedList比較占優(yōu)勢(shì)仆葡,因?yàn)锳rrayList要移動(dòng)數(shù)據(jù)赏参。
ArrayList和LinkedList是兩個(gè)集合 類,用于存儲(chǔ)一系列的對(duì)象引用(references)沿盅。例如我們可以用ArrayList來(lái)存儲(chǔ)一系列的String或者Integer把篓。那么 ArrayList和LinkedList在性能上有什么差別呢?什么時(shí)候應(yīng)該用ArrayList什么時(shí)候又該用LinkedList呢腰涧?
1韧掩、ArrayList和Vector的區(qū)別
2、HashMap和Hashtable的區(qū)別
3窖铡、List疗锐、Map坊谁、Set 有什么區(qū)別?
1、ArrayList和Vector的區(qū)別
這兩個(gè)類都實(shí)現(xiàn)了List接口(List接口繼承了Collection接口)滑臊,他們都是有序集合口芍,即存儲(chǔ)在這兩個(gè)集合中的元素的位置都是有順序的,相當(dāng)于一種動(dòng)態(tài)的數(shù)組雇卷,我們以后可以按位置索引號(hào)取出某個(gè)元素鬓椭,,并且其中的數(shù)據(jù)是允許重復(fù)的关划,這是HashSet之類的集合的最大不同處小染,HashSet之類的集合不可以按索引號(hào)去檢索其中的元素,也不允許有重復(fù)的元素(本來(lái)題目問(wèn)的與hashset沒(méi)有任何關(guān)系贮折,但為了說(shuō)清楚ArrayList與Vector的功能裤翩,我們使用對(duì)比方式,更有利于說(shuō)明問(wèn)題)调榄。
接著才說(shuō)ArrayList與Vector的區(qū)別踊赠,這主要包括兩個(gè)方面:.?
(1)同步性:
Vector是線程安全的,也就是說(shuō)是它的方法之間是線程同步的振峻,而ArrayList是線程序不安全的臼疫,它的方法之間是線程不同步的。如果只有一個(gè)線程會(huì)訪問(wèn)到集合扣孟,那最好是使用ArrayList烫堤,因?yàn)樗豢紤]線程安全,效率會(huì)高些凤价;如果有多個(gè)線程會(huì)訪問(wèn)到集合鸽斟,那最好是使用Vector,因?yàn)椴恍枰覀冏约涸偃タ紤]和編寫(xiě)線程安全的代碼利诺。
備注:對(duì)于Vector&ArrayList富蓄、Hashtable&HashMap,要記住線程安全的問(wèn)題慢逾,記住Vector與Hashtable是舊的立倍,是java一誕生就提供了的,它們是線程安全的侣滩,ArrayList與HashMap是java2時(shí)才提供的口注,它們是線程不安全的。所以君珠,我們講課時(shí)先講老的寝志。
(2)數(shù)據(jù)增長(zhǎng):
ArrayList與Vector都有一個(gè)初始的容量大小,當(dāng)存儲(chǔ)進(jìn)它們里面的元素的個(gè)數(shù)超過(guò)了容量時(shí),就需要增加ArrayList與Vector的存儲(chǔ)空間材部,每次要增加存儲(chǔ)空間時(shí)毫缆,不是只增加一個(gè)存儲(chǔ)單元,而是增加多個(gè)存儲(chǔ)單元乐导,每次增加的存儲(chǔ)單元的個(gè)數(shù)在內(nèi)存空間利用與程序效率之間要取得一定的平衡苦丁。Vector默認(rèn)增長(zhǎng)為原來(lái)兩倍,而ArrayList的增長(zhǎng)策略在文檔中沒(méi)有明確規(guī)定(從源代碼看到的是增長(zhǎng)為原來(lái)的1.5倍)兽叮。ArrayList與Vector都可以設(shè)置初始的空間大小芬骄,Vector還可以設(shè)置增長(zhǎng)的空間大小猾愿,而ArrayList沒(méi)有提供設(shè)置增長(zhǎng)空間的方法鹦聪。
? ? 總結(jié):即Vector增長(zhǎng)原來(lái)的一倍,ArrayList增加原來(lái)的0.5倍蒂秘。
2泽本、HashMap和Hashtable的區(qū)別
HashMap是Hashtable的輕量級(jí)實(shí)現(xiàn)(非線程安全的實(shí)現(xiàn)),他們都完成了Map接口姻僧,主要區(qū)別在于HashMap允許空(null)鍵值(key),由于非線程安全规丽,在只有一個(gè)線程訪問(wèn)的情況下,效率要高于Hashtable撇贺。?
HashMap允許將null作為一個(gè)entry的key或者value赌莺,而Hashtable不允許。?
HashMap把Hashtable的contains方法去掉了松嘶,改成containsvalue和containsKey艘狭。因?yàn)閏ontains方法容易讓人引起誤解。?
Hashtable繼承自Dictionary類翠订,而HashMap是Java1.2引進(jìn)的Map interface的一個(gè)實(shí)現(xiàn)巢音。?
最大的不同是,Hashtable的方法是Synchronize的尽超,而HashMap不是官撼,在多個(gè)線程訪問(wèn)Hashtable時(shí),不需要自己為它的方法實(shí)現(xiàn)同步似谁,而HashMap 就必須為之提供外同步傲绣。?
Hashtable和HashMap采用的hash/rehash算法都大概一樣,所以性能不會(huì)有很大的差異巩踏。
就HashMap與HashTable主要從三方面來(lái)說(shuō)秃诵。?
一.歷史原因:Hashtable是基于陳舊的Dictionary類的,HashMap是Java 1.2引進(jìn)的Map接口的一個(gè)實(shí)現(xiàn)?
二.同步性:Hashtable是線程安全的蛀缝,也就是說(shuō)是同步的顷链,而HashMap是線程序不安全的,不是同步的?
三.值:只有HashMap可以讓你將空值作為一個(gè)表的條目的key或value 。
3嗤练、List榛了、Map、Set 有什么區(qū)別
List與Set具有相似性煞抬,它們都是單列元素的集合霜大,所以,它們有一個(gè)功共同的父接口革答,叫Collection战坤。Set里面不允許有重復(fù)的元素,所謂重復(fù)残拐,即不能有兩個(gè)相等(注意途茫,不是僅僅是相同)的對(duì)象 ,即假設(shè)Set集合中有了一個(gè)A對(duì)象溪食,現(xiàn)在我要向Set集合再存入一個(gè)B對(duì)象囊卜,但B對(duì)象與A對(duì)象equals相等,則B對(duì)象存儲(chǔ)不進(jìn)去错沃,所以栅组,Set集合的add方法有一個(gè)boolean的返回值,當(dāng)集合中沒(méi)有某個(gè)元素枢析,此時(shí)add方法可成功加入該元素時(shí)玉掸,則返回true,當(dāng)集合含有與某個(gè)元素equals相等的元素時(shí)醒叁,此時(shí)add方法無(wú)法加入該元素司浪,返回結(jié)果為false。Set取元素時(shí)辐益,沒(méi)法說(shuō)取第幾個(gè)断傲,只能以Iterator接口取得所有的元素,再逐一遍歷各個(gè)元素智政。
List表示有先后順序的集合认罩, 注意,不是那種按年齡续捂、按大小垦垂、按價(jià)格之類的排序。當(dāng)我們多次調(diào)用add(Obj e)方法時(shí)牙瓢,每次加入的對(duì)象就像火車站買票有排隊(duì)順序一樣劫拗,按先來(lái)后到的順序排序。有時(shí)候矾克,也可以插隊(duì)页慷,即調(diào)用add(int index,Obj e)方法,就可以指定當(dāng)前對(duì)象在集合中的存放位置。一個(gè)對(duì)象可以被反復(fù)存儲(chǔ)進(jìn)List中酒繁,每調(diào)用一次add方法滓彰,這個(gè)對(duì)象就被插入進(jìn)集合中一次,其實(shí)州袒,并不是把這個(gè)對(duì)象本身存儲(chǔ)進(jìn)了集合中揭绑,而是在集合中用一個(gè)索引變量指向這個(gè)對(duì)象,當(dāng)這個(gè)對(duì)象被add多次時(shí)郎哭,即相當(dāng)于集合中有多個(gè)索引指向了這個(gè)對(duì)象他匪,如圖x所示。List除了可以以Iterator接口取得所有的元素夸研,再逐一遍歷各個(gè)元素之外邦蜜,還可以調(diào)用get(index i)來(lái)明確說(shuō)明取第幾個(gè)。
Map與List和Set不同陈惰,它是雙列的集合畦徘,其中有put方法毕籽,定義如下:put(obj key,obj value)抬闯,每次存儲(chǔ)時(shí),要存儲(chǔ)一對(duì)key/value关筒,不能存儲(chǔ)重復(fù)的key溶握,這個(gè)重復(fù)的規(guī)則也是按equals比較相等。取則可以根據(jù)key獲得相應(yīng)的value蒸播,即get(Object key)返回值為key 所對(duì)應(yīng)的value睡榆。另外,也可以獲得所有的key的結(jié)合袍榆,還可以獲得所有的value的結(jié)合胀屿,還可以獲得key和value組合成的Map.Entry對(duì)象的集合。
List 以特定次序來(lái)持有元素包雀,可有重復(fù)元素宿崭。Set 無(wú)法擁有重復(fù)元素,內(nèi)部排序。Map 保存key-value值才写,value可多值葡兑。
HashSet按照hashcode值的某種運(yùn)算方式進(jìn)行存儲(chǔ),而不是直接按hashCode值的大小進(jìn)行存儲(chǔ)赞草。例如讹堤,”abc” —> 78,”def” —> 62厨疙,”xyz” —> 65在hashSet中的存儲(chǔ)順序不是62,65,78洲守,這些問(wèn)題感謝以前一個(gè)叫崔健的學(xué)員提出,最后通過(guò)查看源代碼給他解釋清楚,看本次培訓(xùn)學(xué)員當(dāng)中有多少能看懂源碼梗醇。LinkedHashSet按插入的順序存儲(chǔ)暑始,那被存儲(chǔ)對(duì)象的hashcode方法還有什么作用呢?學(xué)員想想!hashset集合比較兩個(gè)對(duì)象是否相等婴削,首先看hashcode方法是否相等廊镜,然后看equals方法是否相等。new 兩個(gè)Student插入到HashSet中唉俗,看HashSet的size嗤朴,實(shí)現(xiàn)hashcode和equals方法后再看size。
同一個(gè)對(duì)象可以在Vector中加入多次虫溜。往集合里面加元素雹姊,相當(dāng)于集合里用一根繩子連接到了目標(biāo)對(duì)象。往HashSet中卻加不了多次的衡楞。?