2018-04-11 Java集合類

原文:https://blog.csdn.net/touchSea/article/details/750923

java.util包中就包含了一系列重要的集合類他宛,而對于集合類,主要需要掌握的就是它的內(nèi)部結(jié)構(gòu),以及遍歷集合的迭代模式客冈。

Collection接口

Collection是最基本的集合接口,一個(gè)Collection代表一組Object拗馒,即Collection的元素(Elements)冗茸。Collection接口的類都必須提供兩個(gè)標(biāo)準(zhǔn)的構(gòu)造函數(shù):無參數(shù)的構(gòu)造函數(shù)用于創(chuàng)建一個(gè)空的Collection,有一個(gè)Collection參數(shù)的構(gòu)造函數(shù)用于創(chuàng)建一個(gè)新的Collection榴捡,這個(gè)新的Collection與傳入的Collection有相同的元素杈女。后一個(gè)構(gòu)造函數(shù)允許用戶復(fù)制一個(gè)Collection。

如何遍歷Collection中的每一個(gè)元素?不論Collection的實(shí)際類型如何碧信,它都支持一個(gè)iterator()的方法赊琳,該方法返回一個(gè)迭代子,使用該迭代子即可逐一訪問Collection中每一個(gè)元素砰碴。典型的用法如下:

Iterator it = collection.iterator(); // 獲得一個(gè)迭代子

while(it.hasNext()) {

Object obj = it.next(); // 得到下一個(gè)元素

}

由Collection接口派生的兩個(gè)接口是List和Set躏筏。

List接口

List是有序的Collection,使用此接口能夠精確的控制每個(gè)元素插入的位置呈枉。用戶能夠使用索引來訪問List中的元素趁尼,這類似于Java的數(shù)組。和下面要提到的Set不同,List允許有相同的元素礼华。

實(shí)現(xiàn)List接口的常用類有LinkedList给猾,ArrayList,Vector和Stack芝囤。

LinkedList類

LinkedList實(shí)現(xiàn)了List接口,允許null元素辛萍。此外LinkedList提供額外的get悯姊,remove,insert方法在LinkedList的首部或尾部贩毕。這些操作使LinkedList可被用作堆棧(stack)悯许,隊(duì)列(queue)或雙向隊(duì)列(deque)。

注意LinkedList沒有同步方法辉阶。如果多個(gè)線程同時(shí)訪問一個(gè)List先壕,則必須自己實(shí)現(xiàn)訪問同步。一種解決方法是在創(chuàng)建List時(shí)構(gòu)造一個(gè)同步的List:

List list = Collections.synchronizedList(new LinkedList(...));

ArrayList類

ArrayList實(shí)現(xiàn)了可變大小的數(shù)組谆甜。它允許所有元素垃僚,包括null。ArrayList沒有同步店印。 size冈在,isEmpty,get按摘,set方法運(yùn)行時(shí)間為常數(shù)包券。但是add方法開銷為分?jǐn)偟某?shù),添加n個(gè)元素需要O(n)的時(shí)間炫贤。其他的方法運(yùn)行時(shí)間為線性溅固。

每個(gè)ArrayList實(shí)例都有一個(gè)容量(Capacity),即用于存儲(chǔ)元素的數(shù)組的大小兰珍。這個(gè)容量可隨著不斷添加新元素而自動(dòng)增加侍郭,但是增長算法并沒有定義。當(dāng)需要插入大量元素時(shí),在插入前可以調(diào)用ensureCapacity方法來增加ArrayList的容量以提高插入效率亮元。   和LinkedList一樣猛计,ArrayList也是非同步的(unsynchronized)。

Vector類

Vector非常類似ArrayList爆捞,但是Vector是同步的奉瘤。由Vector創(chuàng)建的Iterator,雖然和ArrayList創(chuàng)建的Iterator是同一接口煮甥,但是盗温,因?yàn)閂ector是同步的,當(dāng)一個(gè)Iterator被創(chuàng)建而且正在被使用成肘,另一個(gè)線程改變了Vector的狀態(tài)(例如卖局,添加或刪除了一些元素),這時(shí)調(diào)用Iterator的方法時(shí)將拋出ConcurrentModificationException双霍,因此必須捕獲該異常砚偶。

Stack 類

Stack繼承自Vector,實(shí)現(xiàn)一個(gè)后進(jìn)先出的堆棧洒闸。Stack提供5個(gè)額外的方法使得Vector得以被當(dāng)作堆棧使用蟹演。基本的push和pop方法顷蟀,還有peek方法得到棧頂?shù)脑兀琫mpty方法測試堆棧是否為空骡技,search方法檢測一個(gè)元素在堆棧中的位置鸣个。Stack剛創(chuàng)建后是空棧。

Set接口

Set是一種不包含重復(fù)的元素的Collection布朦,即任意的兩個(gè)元素e1和e2都有e1.equals(e2)=false囤萤,Set最多有一個(gè)null元素。   很明顯是趴,Set的構(gòu)造函數(shù)有一個(gè)約束條件涛舍,傳入的Collection參數(shù)不能包含重復(fù)的元素。   請注意:必須小心操作可變對象(Mutable Object)唆途。如果一個(gè)Set中的可變元素改變了自身狀態(tài)導(dǎo)致Object.equals(Object)=true將導(dǎo)致一些問題富雅。

Map接口

請注意,Map沒有繼承Collection接口肛搬,Map提供key到value的映射没佑。一個(gè)Map中不能包含相同的key,每個(gè)key只能映射一個(gè)value温赔。Map接口提供3種集合的視圖蛤奢,Map的內(nèi)容可以被當(dāng)作一組key集合,一組value集合,或者一組key-value映射啤贩。

Hashtable類

Hashtable繼承Map接口待秃,實(shí)現(xiàn)一個(gè)key-value映射的哈希表。任何非空(non-null)的對象都可作為key或者value痹屹。

添加數(shù)據(jù)使用put(key, value)章郁,取出數(shù)據(jù)使用get(key),這兩個(gè)基本操作的時(shí)間開銷為常數(shù)痢掠。 Hashtable通過initial capacity和load factor兩個(gè)參數(shù)調(diào)整性能驱犹。通常缺省的load factor 0.75較好地實(shí)現(xiàn)了時(shí)間和空間的均衡。增大load factor可以節(jié)省空間但相應(yīng)的查找時(shí)間將增大足画,這會(huì)影響像get和put這樣的操作雄驹。 使用Hashtable的簡單示例如下,將1淹辞,2医舆,3放到Hashtable中,他們的key分別是”one”象缀,”two”蔬将,”three”:     Hashtable numbers = new Hashtable();

numbers.put(“one”, new Integer(1));

numbers.put(“two”, new Integer(2));

numbers.put(“three”, new Integer(3));

要取出一個(gè)數(shù),比如2央星,用相應(yīng)的key:

Integer n = (Integer)numbers.get(“two”);

System.out.println(“two = ” + n);

由于作為key的對象將通過計(jì)算其散列函數(shù)來確定與之對應(yīng)的value的位置霞怀,因此任何作為key的對象都必須實(shí)現(xiàn)hashCode和equals方法。hashCode和equals方法繼承自根類Object莉给,如果你用自定義的類當(dāng)作key的話毙石,要相當(dāng)小心,按照散列函數(shù)的定義颓遏,如果兩個(gè)對象相同徐矩,即obj1.equals(obj2)=true,則它們的hashCode必須相同叁幢,但如果兩個(gè)對象不同滤灯,則它們的hashCode不一定不同,如果兩個(gè)不同對象的hashCode相同曼玩,這種現(xiàn)象稱為沖突鳞骤,沖突會(huì)導(dǎo)致操作哈希表的時(shí)間開銷增大,所以盡量定義好的hashCode()方法黍判,能加快哈希表的操作弟孟。   如果相同的對象有不同的hashCode,對哈希表的操作會(huì)出現(xiàn)意想不到的結(jié)果(期待的get方法返回null)样悟,要避免這種問題拂募,只需要牢記一條:要同時(shí)復(fù)寫equals方法和hashCode方法庭猩,而不要只寫其中一個(gè)。   Hashtable是同步的陈症。

HashMap類

HashMap和Hashtable類似蔼水,不同之處在于HashMap是非同步的,并且允許null录肯,即null value和null key趴腋。,但是將HashMap視為Collection時(shí)(values()方法可返回Collection)论咏,其迭代子操作時(shí)間開銷和HashMap的容量成比例优炬。因此,如果迭代操作的性能相當(dāng)重要的話厅贪,不要將HashMap的初始化容量設(shè)得過高蠢护,或者load factor過低。

WeakHashMap類

WeakHashMap是一種改進(jìn)的HashMap养涮,它對key實(shí)行“弱引用”葵硕,如果一個(gè)key不再被外部所引用,那么該key可以被GC回收贯吓。

總結(jié)

如果涉及到堆棧懈凹,隊(duì)列等操作,應(yīng)該考慮用List悄谐,對于需要快速插入介评,刪除元素,應(yīng)該使用LinkedList爬舰,如果需要快速隨機(jī)訪問元素威沫,應(yīng)該使用ArrayList。

如果程序在單線程環(huán)境中洼专,或者訪問僅僅在一個(gè)線程中進(jìn)行,考慮非同步的類孵构,其效率較高屁商,如果多個(gè)線程可能同時(shí)操作一個(gè)類,應(yīng)該使用同步的類颈墅。

要特別注意對哈希表的操作蜡镶,作為key的對象要正確復(fù)寫equals和hashCode方法。

盡量返回接口而非實(shí)際的類型恤筛,如返回List而非ArrayList官还,這樣如果以后需要將ArrayList換成LinkedList時(shí),客戶端代碼不用改變毒坛。這就是針對抽象編程望伦。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末林说,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子屯伞,更是在濱河造成了極大的恐慌腿箩,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件劣摇,死亡現(xiàn)場離奇詭異珠移,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)末融,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門钧惧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人勾习,你說我怎么就攤上這事浓瞪。” “怎么了语卤?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵追逮,是天一觀的道長。 經(jīng)常有香客問我粹舵,道長钮孵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任眼滤,我火速辦了婚禮巴席,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘诅需。我一直安慰自己漾唉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布堰塌。 她就那樣靜靜地躺著赵刑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪场刑。 梳的紋絲不亂的頭發(fā)上般此,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天,我揣著相機(jī)與錄音牵现,去河邊找鬼铐懊。 笑死,一個(gè)胖子當(dāng)著我的面吹牛瞎疼,可吹牛的內(nèi)容都是我干的科乎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼贼急,長吁一口氣:“原來是場噩夢啊……” “哼茅茂!你這毒婦竟也來了捏萍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤玉吁,失蹤者是張志新(化名)和其女友劉穎照弥,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體进副,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡这揣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了影斑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片给赞。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖矫户,靈堂內(nèi)的尸體忽然破棺而出片迅,到底是詐尸還是另有隱情,我是刑警寧澤皆辽,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布柑蛇,位于F島的核電站,受9級(jí)特大地震影響驱闷,放射性物質(zhì)發(fā)生泄漏耻台。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一空另、第九天 我趴在偏房一處隱蔽的房頂上張望盆耽。 院中可真熱鬧,春花似錦扼菠、人聲如沸摄杂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽析恢。三九已至,卻和暖如春秧饮,著一層夾襖步出監(jiān)牢的瞬間映挂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來泰國打工浦楣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人咪辱。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓振劳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親油狂。 傳聞我的和親對象是個(gè)殘疾皇子历恐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

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