常用的集合類(lèi)有一下幾種:
List結(jié)構(gòu)的集合類(lèi):ArrayList類(lèi),linkedList類(lèi),Vector類(lèi),Stack類(lèi)
Map結(jié)構(gòu)的集合類(lèi):HashMap類(lèi),Hashtable類(lèi)
Set結(jié)構(gòu)的集合類(lèi):HashSet類(lèi),TreeSet類(lèi)
Queue結(jié)構(gòu)的集合:Queue接口
HashMap和Hashtable的區(qū)別:
HashMap和Hashtable都是java的集合類(lèi),都可以用來(lái)存放java對(duì)象,這是他們的相同點(diǎn)
以下是他們的區(qū)別:
1.歷史原因:
Hashtable是基于陳舊的Dictionary類(lèi)的,HashMap是java 1.2引進(jìn)的Map接口的一個(gè)現(xiàn)實(shí)。
2.同步性:
Hashtable是同步的,這個(gè)類(lèi)中的一些方法保證了Hashtable中的對(duì)象是線程安全的,而HashMap則是異步的,因此HashMap中的對(duì)象并不是線程安全的,因?yàn)橥降囊髸?huì)影響執(zhí)行的效率,所以如果你不需要線程安全的結(jié)合那么使用HashMap是一個(gè)很好的選擇,這樣可以避免由于同步帶來(lái)的不必要的性能開(kāi)銷(xiāo),從而提高效率,我們一般所編寫(xiě)的程序都是異步的,但如果是服務(wù)器端的代碼除外。
3.值:
HashMap可以讓你將空值作為一個(gè)表的條目的key或value
Hashtable是不能放入空值(null)的
ArrayList和Vector的區(qū)別:
ArrayList與Vector都是java的集合類(lèi),都是用來(lái)存放java對(duì)象,這是他們的相同點(diǎn),
區(qū)別:
1.同步性:
Vector是同步的,這個(gè)類(lèi)的一些方法保證了Vector中的對(duì)象的線程安全的,而ArrayList則是異步的,因此ArrayList中的對(duì)象并不 是線程安全的,因?yàn)橥揭髸?huì)影響執(zhí)行的效率,所以你不需要線程安全的集合那么使用ArrayList是一個(gè)很好的選擇,這樣可以避免由于同步帶來(lái)的不必 要的性能開(kāi)銷(xiāo)。
2.數(shù)據(jù)增長(zhǎng):
從內(nèi)部實(shí)現(xiàn)的機(jī)制來(lái)講,ArrayList和Vector都是使用數(shù)組(Array)來(lái)控制集合中的對(duì)象,當(dāng)你向兩種類(lèi)型中增加元素的時(shí)候,如果元素的數(shù)目超過(guò)了內(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)銷(xiāo)。
總結(jié):
1)如果要求線程安全,使用Vector,Hashtable
2)如果不要求線程安全,使用ArrayList,linkedList,HashMap
3)如果要求鍵值對(duì),則使用HashMap,Hashtable
4)如果數(shù)據(jù)量很大,又要求線程安全考慮Vector
1.ArrayList: 元素單個(gè),效率高,多用于查詢
2.Vector: 元素單個(gè),線程安全,多用于查詢
3.linkedList:元素單個(gè),多用于插入和刪除
4.HashMap: 元素成對(duì),元素可為空
5.HashTable: 元素成對(duì),線程安全,元素不可為空
ArrayList
底層是Object數(shù)組,所以ArrayList具有數(shù)組的查詢速度快的優(yōu)點(diǎn)以及增刪速度慢的缺點(diǎn)。
而在linkedList的底層是一種雙向循環(huán)鏈表。在此鏈表上每一個(gè)數(shù)據(jù)節(jié)點(diǎn)都由三部分組成:前指針(指向前面的節(jié)點(diǎn)的位置),數(shù)據(jù),后指針(指向后面的節(jié)點(diǎn)的位置)。最后一個(gè)節(jié)點(diǎn)的后指針指向第一個(gè)節(jié)點(diǎn)的前指針,形成一個(gè)循環(huán)。
雙向循環(huán)鏈表的查詢效率低但是增刪效率高。
ArrayList和linkedList在用法上沒(méi)有區(qū)別,但是在功能上還是有區(qū)別的。
linkedList
經(jīng)常用在增刪操作較多而查詢操作很少的情況下:隊(duì)列和堆棧。
隊(duì)列:先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)。
棧:后進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)。
注意:使用棧的時(shí)候一定不能提供方法讓不是最后一個(gè)元素的元素獲得出棧的機(jī)會(huì)。
Vector
(與ArrayList相似,區(qū)別是Vector是重量級(jí)的組件,使用使消耗的資源比較多。)
結(jié)論:在考慮并發(fā)的情況下用Vector(保證線程的安全)。
在不考慮并發(fā)的情況下用ArrayList(不能保證線程的安全)。
面試經(jīng)驗(yàn)(知識(shí)點(diǎn)):
java.util.stack(stack即為堆棧)的父類(lèi)為Vector??墒莝tack的父類(lèi)是最不應(yīng)該為Vector的。因?yàn)閂ector的底層是數(shù)組,且Vector有g(shù)et方法(意味著它可能訪問(wèn)到并不屬于最后一個(gè)位置元素的其他元素,很不安全)。
對(duì)于堆棧和隊(duì)列只能用push類(lèi)和get類(lèi)。
Stack類(lèi)以后不要輕易使用。
實(shí)現(xiàn)棧一定要用linkedList。
(在JAVA1.5中,collection有queue來(lái)實(shí)現(xiàn)隊(duì)列。)
Set-HashSet實(shí)現(xiàn)類(lèi):
遍歷一個(gè)Set的方法只有一個(gè):迭代器(interator)。
HashSet中元素是無(wú)序的(這個(gè)無(wú)序指的是數(shù)據(jù)的添加順序和后來(lái)的排列順序不同),而且元素不可重復(fù)。
在Object中除了有finalize(),toString(),equals(),還有hashCode()。
HashSet底層用的也是數(shù)組。
當(dāng)向數(shù)組中利用add(Object o)添加對(duì)象的時(shí)候,系統(tǒng)先找對(duì)象的hashCode:
int hc=o.hashCode(); 返回的hashCode為整數(shù)值。
Int I=hc%n;(n為數(shù)組的長(zhǎng)度),取得余數(shù)后,利用余數(shù)向數(shù)組中相應(yīng)的位置添加數(shù)據(jù),以n為6為例,如果I=0則放在數(shù)組a[0]位置,如果I=1,則 放在數(shù)組a[1]位置。如果equals()返回的值為true,則說(shuō)明數(shù)據(jù)重復(fù)。如果equals()返回的值為false,則再找其他的位置進(jìn)行比 較。這樣的機(jī)制就導(dǎo)致兩個(gè)相同的對(duì)象有可能重復(fù)地添加到數(shù)組中,因?yàn)樗麄兊膆ashCode不同。
如果我們能夠使兩個(gè)相同的對(duì)象具有相同hashcode,才能在equals()返回為真。
在實(shí)例中,定義student對(duì)象時(shí)覆蓋它的hashcode。
因?yàn)镾tring類(lèi)是自動(dòng)覆蓋的,所以當(dāng)比較String類(lèi)的對(duì)象的時(shí)候,就不會(huì)出現(xiàn)有兩個(gè)相同的string對(duì)象的情況。
現(xiàn)在,在大部分的JDK中,都已經(jīng)要求覆蓋了hashCode。
結(jié)論:如將自定義類(lèi)用hashSet來(lái)添加對(duì)象,一定要覆蓋hashcode()和equals(),覆蓋的原則是保證當(dāng)兩個(gè)對(duì)象hashcode返回相同的整數(shù),而且equals()返回值為T(mén)rue。
如果偷懶,沒(méi)有設(shè)定equals(),就會(huì)造成返回hashCode雖然結(jié)果相同,但在程序執(zhí)行的過(guò)程中會(huì)多次地調(diào)用equals(),從而影響程序執(zhí)行的效率。
我們要保證相同對(duì)象的返回的hashCode一定相同,也要保證不相同的對(duì)象的hashCode盡可能不同(因?yàn)閿?shù)組的邊界性,hashCode還是可能相同的)。
例子:
public int hashCode(){ return name.hashcode()+age; }
這個(gè)例子保證了相同姓名和年齡的記錄返回的hashCode是相同的。
使用hashSet的優(yōu)點(diǎn):
hashSet的底層是數(shù)組,其查詢效率非常高。而且在增加和刪除的時(shí)候由于運(yùn)用的hashCode的比較開(kāi)確定添加元素的位置,所以不存在元素的偏移,所以效率也非常高。因?yàn)閔ashSet查詢和刪除和增加元素的效率都非常高。
但是hashSet增刪的高效率是通過(guò)花費(fèi)大量的空間換來(lái)的:因?yàn)榭臻g越大,取余數(shù)相同的情況就越小。HashSet這種算法會(huì)建立許多無(wú)用的空間。
使用hashSet類(lèi)時(shí)要注意,如果發(fā)生沖突,就會(huì)出現(xiàn)遍歷整個(gè)數(shù)組的情況,這樣就使得效率非常的低。
以上就是北大青鳥(niǎo)長(zhǎng)沙麓谷校區(qū)Java培訓(xùn)機(jī)構(gòu)小編介紹的“Java五個(gè)最常用的集合類(lèi)之間的區(qū)別和聯(lián)系”的內(nèi)容,希望對(duì)大家有幫助,如有疑問(wèn),請(qǐng)?jiān)诰€咨詢,有專(zhuān)業(yè)老師隨時(shí)為你服務(wù)。
Java入門(mén)到項(xiàng)目免費(fèi)學(xué)習(xí)視頻:
Java零基礎(chǔ)必學(xué)視頻:http://www.bjpowernode.com/v104/
Java入門(mén)到精通視頻教程:http://www.bjpowernode.com/video.html
Java技術(shù)教程:http://www.bjpowernode.com/tutorial/
相關(guān)文章
零基礎(chǔ)怎么自學(xué)Java,完整版Java學(xué)習(xí)路線圖
你還在糾結(jié)學(xué)Java,是自學(xué)還是去培訓(xùn)班嗎
一個(gè)標(biāo)準(zhǔn)的Java程序員如何進(jìn)階?
Java學(xué)習(xí)路線清單,快速進(jìn)階Java
Java編程初學(xué)者要如何進(jìn)階