Java集合框架詳解

一贵白、Java集合框架概述

集合可以看作是一種容器衣吠,用來存儲對象信息锰什。所有集合類都位于java.util包下罚随,但支持多線程的集合類位于java.util.concurrent包下玉工。

  數(shù)組與集合的區(qū)別如下:

  1)數(shù)組長度不可變化而且無法保存具有映射關(guān)系的數(shù)據(jù);集合類用于保存數(shù)量不確定的數(shù)據(jù),以及保存具有映射關(guān)系的數(shù)據(jù)淘菩。

  2)數(shù)組元素既可以是基本類型的值遵班,也可以是對象;集合只能保存對象。

  Java集合類主要由兩個根接口Collection和Map派生出來的潮改,Collection派生出了三個子接口:List狭郑、Set、Queue(Java5新增的隊列)汇在,因此Java集合大致也可分成List翰萨、Set、Queue糕殉、Map四種接口體系亩鬼,(注意:Map不是Collection的子接口)。

  其中List代表了有序可重復(fù)集合阿蝶,可直接根據(jù)元素的索引來訪問;Set代表無序不可重復(fù)集合雳锋,只能根據(jù)元素本身來訪問;Queue是隊列集合;Map代表的是存儲key-value對的集合,可根據(jù)元素的key來訪問value赡磅。

  上圖中淡綠色背景覆蓋的是集合體系中常用的實現(xiàn)類魄缚,分別是ArrayList、LinkedList焚廊、ArrayQueue、HashSet习劫、TreeSet咆瘟、HashMap、TreeMap等實現(xiàn)類诽里。

  二袒餐、Java集合常見接口及實現(xiàn)類

  1. Collection接口常見方法(來源于Java API)

2. Set集合

  Set集合與Collection的方法相同,由于Set集合不允許存儲相同的元素谤狡,所以如果把兩個相同元素添加到同一個Set集合灸眼,則添加操作失敗,新元素不會被加入墓懂,add()方法返回false焰宣。為了幫助理解,請看下面代碼示例:

public class Test {

  public static void main(String[] args) {

  Set set = new HashSet();

  set.add(“hello world”);

  set.add(“hello 冰湖一角”);

  set.add(“hello 冰湖一角”);//添加不進(jìn)去

  System.out.println(“集合中元素個數(shù):”+set.size());

  System.out.println(“集合中元素為:”+set.toString());

  }

  }

運行結(jié)果如下:

  集合中元素個數(shù):2

  集合中元素為:[hello world, hello 冰湖一角]

  分析:由于String類中重寫了hashCode()和equals()方法捕仔,用來比較指向的字符串對象所存儲的字符串是否相等匕积。所以這里的第二個"hello

冰湖一角"是加不進(jìn)去的盈罐。

  下面著重介紹Set集合幾個常用實現(xiàn)類:

  1)HashSet類

  HashSet是Set集合最常用實現(xiàn)類,是其經(jīng)典實現(xiàn)闪唆。HashSet是按照hash算法來存儲元素的盅粪,因此具有很好的存取和查找性能。

  HashSet具有如下特點:

  ? 不能保證元素的順序悄蕾。

  ? HashSet不是線程同步的票顾,如果多線程操作HashSet集合,則應(yīng)通過代碼來保證其同步帆调。

  ? 集合元素值可以是null奠骄。

  HashSet存儲原理如下:

  當(dāng)向HashSet集合存儲一個元素時,HashSet會調(diào)用該對象的hashCode()方法得到其hashCode值贷帮,然后根據(jù)hashCode值決定該對象的存儲位置戚揭。HashSet集合判斷兩個元素相等的標(biāo)準(zhǔn)是(1)兩個對象通過equals()方法比較返回true;(2)兩個對象的hashCode()方法返回值相等。因此撵枢,如果(1)和(2)有一個不滿足條件民晒,則認(rèn)為這兩個對象不相等,可以添加成功锄禽。如果兩個對象的hashCode()方法返回值相等潜必,但是兩個對象通過equals()方法比較返回false,HashSet會以鏈?zhǔn)浇Y(jié)構(gòu)將兩個對象保存在同一位置沃但,這將導(dǎo)致性能下降磁滚,因此在編碼時應(yīng)避免出現(xiàn)這種情況。

  HashSet查找原理如下:

  基于HashSet以上的存儲原理宵晚,在查找元素時垂攘,HashSet先計算元素的HashCode值(也就是調(diào)用對象的hashCode方法的返回值),然后直接到hashCode值對應(yīng)的位置去取出元素即可淤刃,這就是HashSet速度很快的原因晒他。

  重寫hashCode()方法的基本原則如下:

  ? 在程序運行過程中,同一個對象的hashCode()方法返回值應(yīng)相同逸贾。

  ? 當(dāng)兩個對象通過equals()方法比較返回true時陨仅,這兩個對象的hashCode()方法返回值應(yīng)該相等。

  ? 對象中用作equals()方法比較標(biāo)準(zhǔn)的實例變量铝侵,都應(yīng)該用于計算hashCode值灼伤。

  2)LinkedHashSet類

  LinkedHashSet是HashSet的一個子類,具有HashSet的特性咪鲜,也是根據(jù)元素的hashCode值來決定元素的存儲位置狐赡。但它使用鏈表維護(hù)元素的次序,元素的順序與添加順序一致嗜诀。由于LinkedHashSet需要維護(hù)元素的插入順序猾警,因此性能略低于HashSet孔祸,但在迭代訪問Set里的全部元素時由很好的性能。

  3)TreeSet類

  TreeSet時SortedSet接口的實現(xiàn)類发皿,TreeSet可以保證元素處于排序狀態(tài)崔慧,它采用紅黑樹的數(shù)據(jù)結(jié)構(gòu)來存儲集合元素。TreeSet支持兩種排序方法:自然排序和定制排序穴墅,默認(rèn)采用自然排序惶室。

  ? 自然排序

  TreeSet會調(diào)用集合元素的compareTo(Object

obj)方法來比較元素的大小關(guān)系,然后將元素按照升序排列玄货,這就是自然排序皇钞。如果試圖將一個對象添加到TreeSet集合中,則該對象必須實現(xiàn)Comparable接口松捉,否則會拋出異常夹界。當(dāng)一個對象調(diào)用方法與另一個對象比較時,例如obj1.compareTo(obj2)隘世,如果該方法返回0可柿,則兩個對象相等;如果返回一個正數(shù),則obj1大于obj2;如果返回一個負(fù)數(shù)丙者,則obj1小于obj2复斥。

  Java常用類中已經(jīng)實現(xiàn)了Comparable接口的類有以下幾個:

  ? BigDecimal、BigDecimal以及所有數(shù)值型對應(yīng)的包裝類:按照它們對應(yīng)的數(shù)值大小進(jìn)行比較械媒。

  ? Charchter:按照字符的unicode值進(jìn)行比較目锭。

  ? Boolean:true對應(yīng)的包裝類實例大于false對應(yīng)的包裝類實例。

  ? String:按照字符串中的字符的unicode值進(jìn)行比較纷捞。

  ? Date痢虹、Time:后面的時間、日期比前面的時間主儡、日期大世分。

  對于TreeSet集合而言,它判斷兩個對象是否相等的標(biāo)準(zhǔn)是:兩個對象通過compareTo(Object

obj)方法比較是否返回0缀辩,如果返回0則相等。

  ? 定制排序

  想要實現(xiàn)定制排序踪央,需要在創(chuàng)建TreeSet集合對象時臀玄,提供一個Comparator對象與該TreeSet集合關(guān)聯(lián),由Comparator對象負(fù)責(zé)集合元素的排序邏輯畅蹂。

  綜上:自然排序?qū)崿F(xiàn)的是Comparable接口健无,定制排序?qū)崿F(xiàn)的是Comparator接口。(具體代碼實現(xiàn)會在后續(xù)章節(jié)中講解)

  4)EnumSet類

  EnumSet是一個專為枚舉類設(shè)計的集合類液斜,不允許添加null值累贤。EnumSet的集合元素也是有序的叠穆,它以枚舉值在Enum類內(nèi)的定義順序來決定集合元素的順序。

  5)各Set實現(xiàn)類的性能分析

  HashSet的性能比TreeSet的性能好(特別是添加臼膏,查詢元素時)硼被,因為TreeSet需要額外的紅黑樹算法維護(hù)元素的次序,如果需要一個保持排序的Set時才用TreeSet渗磅,否則應(yīng)該使用HashSet嚷硫。

  LinkedHashSet是HashSet的子類,由于需要鏈表維護(hù)元素的順序始鱼,所以插入和刪除操作比HashSet要慢仔掸,但遍歷比HashSet快。

  EnumSet是所有Set實現(xiàn)類中性能最好的医清,但它只能 保存同一個枚舉類的枚舉值作為集合元素起暮。

  以上幾個Set實現(xiàn)類都是線程不安全的,如果多線程訪問会烙,必須手動保證集合的同步性负懦,這在后面的章節(jié)中會講到。

  3. List集合

  List集合代表一個有序持搜、可重復(fù)集合密似,集合中每個元素都有其對應(yīng)的順序索引。List集合默認(rèn)按照元素的添加順序設(shè)置元素的索引葫盼,可以通過索引(類似數(shù)組的下標(biāo))來訪問指定位置的集合元素残腌。

  實現(xiàn)List接口的集合主要有:ArrayList、LinkedList贫导、Vector抛猫、Stack。

  1)ArrayList

  ArrayList是一個動態(tài)數(shù)組孩灯,也是我們最常用的集合闺金,是List類的典型實現(xiàn)。它允許任何符合規(guī)則的元素插入甚至包括null峰档。每一個ArrayList都有一個初始容量(10)败匹,該容量代表了數(shù)組的大小。隨著容器中的元素不斷增加讥巡,容器的大小也會隨著增加掀亩。在每次向容器中增加元素的同時都會進(jìn)行容量檢查,當(dāng)快溢出時欢顷,就會進(jìn)行擴(kuò)容操作槽棍。所以如果我們明確所插入元素的多少,最好指定一個初始容量值,避免過多的進(jìn)行擴(kuò)容操作而浪費時間炼七、效率缆巧。

  ArrayList擅長于隨機(jī)訪問。同時ArrayList是非同步的豌拙。

  2)LinkedList

  LinkedList是List接口的另一個實現(xiàn)陕悬,除了可以根據(jù)索引訪問集合元素外,LinkedList還實現(xiàn)了Deque接口姆蘸,可以當(dāng)作雙端隊列來使用墩莫,也就是說,既可以當(dāng)作“棾逊螅”使用狂秦,又可以當(dāng)作隊列使用。

  LinkedList的實現(xiàn)機(jī)制與ArrayList的實現(xiàn)機(jī)制完全不同推捐,ArrayLiat內(nèi)部以數(shù)組的形式保存集合的元素裂问,所以隨機(jī)訪問集合元素有較好的性能;LinkedList內(nèi)部以鏈表的形式保存集合中的元素,所以隨機(jī)訪問集合中的元素性能較差牛柒,但在插入刪除元素時有較好的性能堪簿。

  3)Vector

  與ArrayList相似,但是Vector是同步的皮壁。所以說Vector是線程安全的動態(tài)數(shù)組椭更。它的操作與ArrayList幾乎一樣。

  4)Stack

  Stack繼承自Vector蛾魄,實現(xiàn)一個后進(jìn)先出的堆棧虑瀑。Stack提供5個額外的方法使得Vector得以被當(dāng)作堆棧使用〉涡耄基本的push和pop

方法舌狗,還有peek方法得到棧頂?shù)脑兀琫mpty方法測試堆棧是否為空扔水,search方法檢測一個元素在堆棧中的位置痛侍。Stack剛創(chuàng)建后是空棧。

  5)Iterator接口和ListIterator接口

  Iterator是一個接口魔市,它是集合的迭代器主届。集合可以通過Iterator去遍歷集合中的元素。Iterator提供的API接口如下:

  ? boolean hasNext():判斷集合里是否存在下一個元素待德。如果有岂膳,hasNext()方法返回 true。

  ? Object next():返回集合里下一個元素磅网。

  ? void remove():刪除集合里上一次next方法返回的元素。

  ListIterator接口繼承Iterator接口筷屡,提供了專門操作List的方法涧偷。ListIterator接口在Iterator接口的基礎(chǔ)上增加了以下幾個方法:

  ? boolean hasPrevious():判斷集合里是否存在上一個元素簸喂。如果有,該方法返回 true燎潮。

  ? Object previous():返回集合里上一個元素溉浙。

  ? void add(Object o):在指定位置插入一個元素宏胯。

  以上兩個接口相比較,不難發(fā)現(xiàn),ListIterator增加了向前迭代的功能(Iterator只能向后迭代)衡楞,ListIterator還可以通過add()方法向List集合中添加元素(Iterator只能刪除元素)。

  4. Map集合

  Map接口采用鍵值對Map的存儲方式蹄咖,保存具有映射關(guān)系的數(shù)據(jù)泽示,因此,Map集合里保存兩組值秉剑,一組值用于保存Map里的key泛豪,另外一組值用于保存Map里的value,key和value可以是任意引用類型的數(shù)據(jù)侦鹏。key值不允許重復(fù)诡曙,可以為null。如果添加key-value對時Map中已經(jīng)有重復(fù)的key略水,則新添加的value會覆蓋該key原來對應(yīng)的value价卤。常用實現(xiàn)類有HashMap、LinkedHashMap渊涝、TreeMap等慎璧。

  Map常見方法(來源于API)如下:

1)HashMap與Hashtable

  HashMap與Hashtable是Map接口的兩個典型實現(xiàn),它們之間的關(guān)系完全類似于ArrayList與Vertor驶赏。HashTable是一個古老的Map實現(xiàn)類炸卑,它提供的方法比較繁瑣,目前基本不用了煤傍,HashMap與Hashtable主要存在以下兩個典型區(qū)別:

  ? HashMap是線程不安全盖文,HashTable是線程安全的。

  ?

HashMap可以使用null值最為key或value;Hashtable不允許使用null值作為key和value蚯姆,如果把null放進(jìn)HashTable中五续,將會發(fā)生空指針異常。

  為了成功的在HashMap和Hashtable中存儲和獲取對象龄恋,用作key的對象必須實現(xiàn)hashCode()方法和equals()方法疙驾。

  HashMap工作原理如下:

  HashMap基于hashing原理,通過put()和get()方法存儲和獲取對象郭毕。當(dāng)我們將鍵值對傳遞給put()方法時它碎,它調(diào)用建對象的hashCode()方法來計算hashCode值,然后找到bucket位置來儲存值對象。當(dāng)獲取對象時扳肛,通過建對象的equals()方法找到正確的鍵值對傻挂,然后返回對象。HashMap使用鏈表來解決碰撞問題挖息,當(dāng)發(fā)生碰撞了金拒,對象將會存儲在鏈表的下一個節(jié)點中。

  2)LinkedHashMap實現(xiàn)類

  LinkedHashMap使用雙向鏈表來維護(hù)key-value對的次序(其實只需要考慮key的次序即可)套腹,該鏈表負(fù)責(zé)維護(hù)Map的迭代順序绪抛,與插入順序一致,因此性能比HashMap低电禀,但在迭代訪問Map里的全部元素時有較好的性能幢码。

  3)Properties

  Properties類時Hashtable類的子類,它相當(dāng)于一個key鞭呕、value都是String類型的Map蛤育,主要用于讀取配置文件。

  4)TreeMap實現(xiàn)類

  TreeMap是SortedMap的實現(xiàn)類葫松,是一個紅黑樹的數(shù)據(jù)結(jié)構(gòu)瓦糕,每個key-value對作為紅黑樹的一個節(jié)點。TreeMap存儲key-value對時腋么,需要根據(jù)key對節(jié)點進(jìn)行排序咕娄。TreeMap也有兩種排序方式:

  ?

自然排序:TreeMap的所有key必須實現(xiàn)Comparable接口,而且所有的key應(yīng)該是同一個類的對象珊擂,否則會拋出ClassCastException圣勒。

  ? 定制排序:創(chuàng)建TreeMap時,傳入一個Comparator對象摧扇,該對象負(fù)責(zé)對TreeMap中的所有key進(jìn)行排序圣贸。

  5)各Map實現(xiàn)類的性能分析

  ? HashMap通常比Hashtable(古老的線程安全的集合)要快

  ? TreeMap通常比HashMap、Hashtable要慢扛稽,因為TreeMap底層采用紅黑樹來管理key-value吁峻。

  ? LinkedHashMap比HashMap慢一點,因為它需要維護(hù)鏈表來爆出key-value的插入順序

Java交流裙:109–1181–875

相關(guān)Java視頻學(xué)習(xí)資料

搭建springMVC+spring+mybatis框架

http://www.makeru.com.cn/live/1394_724.html?s=156461

框架mybatis

http://www.makeru.com.cn/live/1394_846.html?s=156461

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末在张,一起剝皮案震驚了整個濱河市用含,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌帮匾,老刑警劉巖啄骇,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瘟斜,居然都是意外死亡缸夹,警方通過查閱死者的電腦和手機(jī)痪寻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來明未,“玉大人槽华,你說我怎么就攤上這事√送祝” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵佣蓉,是天一觀的道長披摄。 經(jīng)常有香客問我,道長勇凭,這世上最難降的妖魔是什么疚膊? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮虾标,結(jié)果婚禮上寓盗,老公的妹妹穿的比我還像新娘。我一直安慰自己璧函,他們只是感情好傀蚌,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蘸吓,像睡著了一般善炫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上库继,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天箩艺,我揣著相機(jī)與錄音,去河邊找鬼宪萄。 笑死艺谆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拜英。 我是一名探鬼主播静汤,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼聊记!你這毒婦竟也來了撒妈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤排监,失蹤者是張志新(化名)和其女友劉穎狰右,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舆床,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡棋蚌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年嫁佳,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谷暮。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蒿往,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出湿弦,到底是詐尸還是另有隱情瓤漏,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布颊埃,位于F島的核電站蔬充,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏班利。R本人自食惡果不足惜饥漫,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望罗标。 院中可真熱鬧庸队,春花似錦、人聲如沸闯割。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纽谒。三九已至证膨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鼓黔,已是汗流浹背央勒。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留澳化,地道東北人崔步。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像缎谷,于是被迫代替她去往敵國和親井濒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353