Java集合類簡介及其遍歷總結(jié)

Java集合類簡介

Java集合類主要由兩個接口派生而出: Collection 和 Map 箱锐。Java集合大致可以分為Set、List劳较、Queue和Map四種體系驹止。其繼承樹關(guān)系如圖:


Java集合框架圖

上述類圖中浩聋,實線邊框的是實現(xiàn)類,比如ArrayList臊恋,LinkedList衣洁,HashMap等,折線邊框的是抽象類抖仅,比如AbstractCollection坊夫,AbstractList,AbstractMap等撤卢,而點線邊框的是接口环凿,比如Collection,Iterator放吩,List等智听。各體系集合的特點概述如下:

  • Set體系集合:代表無序、不可重復(fù)的集合渡紫;
  • List體系集合:代表有序到推、重復(fù)的集合;
  • Map體系集合:代表具有映射關(guān)系的集合惕澎;
  • Queue體系集合莉测,代表一種隊列集合實現(xiàn)。(Java 5 增加)

Java集合和數(shù)組的區(qū)別

1唧喉、數(shù)組長度在初始化時指定捣卤,意味著只能保存定長的數(shù)據(jù)。而集合可以保存數(shù)量不確定的數(shù)據(jù)欣喧。同時可以保存具有映射關(guān)系的數(shù)據(jù)(即關(guān)聯(lián)數(shù)組腌零,鍵值對 key-value)。

2唆阿、數(shù)組元素即可以是基本類型的值益涧,也可以是對象。集合里只能保存對象(實際上只是保存對象的引用變量)驯鳖,基本數(shù)據(jù)類型的變量要轉(zhuǎn)換成對應(yīng)的包裝類才能放入集合類中闲询。Java 5 增加泛型以后還可以記住容器中對象的數(shù)據(jù)類型。

集合的遍歷

通用方式


Iterator it = list.iterator();
while(it.hasNext()) { 
 Object obj = it.next();
}

Map遍歷方式

1浅辙、通過獲取所有的key按照key來遍歷

//Set<Integer> set = map.keySet(); //得到所有key的集合
for (Integer in : map.keySet()) {
    String str = map.get(in);//得到每個key多對用value的值
}

2扭弧、通過Map.entrySet使用iterator遍歷key和value

Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator();
while (it.hasNext()) {
     Map.Entry<Integer, String> entry = it.next();
       System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}

3、通過Map.entrySet遍歷key和value记舆,推薦鸽捻,尤其是容量大時

for (Map.Entry<Integer, String> entry : map.entrySet()) {
    //Map.entry<Integer,String> 映射項(鍵-值對)  有幾個方法:用上面的名字entry
    //entry.getKey() ;entry.getValue(); entry.setValue();
    //map.entrySet()  返回此映射中包含的映射關(guān)系的 Set視圖。
    System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}

4、通過Map.values()遍歷所有的value御蒲,但不能遍歷key

for (String v : map.values()) {
    System.out.println("value= " + v);
}

List遍歷方式

第一種:

Iterator iterator = list.iterator();
for(iterator.hasNext();){                    
    int i = (Integer) iterator.next();                   
    System.out.println(i);               
}

第二種:

Iterator iterator = list.iterator();
while(iterator.hasNext()){
    int i = (Integer) iterator.next();
    System.out.println(i);
}

第三種:

for (Object object : list) { 
    System.out.println(object); 
}

第四種:

for(int i = 0 ;i<list.size();i++) {  
    int j= (Integer) list.get(i);
    System.out.println(j);  
}

數(shù)據(jù)元素是怎樣在內(nèi)存中存放的衣赶?

主要有2種存儲方式:

1、順序存儲厚满,Random Access(Direct Access):
這種方式府瞄,相鄰的數(shù)據(jù)元素存放于相鄰的內(nèi)存地址中,整塊內(nèi)存地址是連續(xù)的碘箍∽窆荩可以根據(jù)元素的位置直接計算出內(nèi)存地址,直接進行讀取丰榴。讀取一個特定位置元素的平均時間復(fù)雜度為O(1)货邓。正常來說,只有基于數(shù)組實現(xiàn)的集合多艇,才有這種特性逻恐。Java中以ArrayList為代表像吻。
2峻黍、鏈式存儲,Sequential Access:
這種方式拨匆,每一個數(shù)據(jù)元素姆涩,在內(nèi)存中都不要求處于相鄰的位置,每個數(shù)據(jù)元素包含它下一個元素的內(nèi)存地址惭每。不可以根據(jù)元素的位置直接計算出內(nèi)存地址骨饿,只能按順序讀取元素。讀取一個特定位置元素的平均時間復(fù)雜度為O(n)台腥。主要以鏈表為代表宏赘。Java中以LinkedList為代表。

每個遍歷方法的實現(xiàn)原理是什么黎侈?

1察署、傳統(tǒng)的for循環(huán)遍歷,基于計數(shù)器的:
遍歷者自己在集合外部維護一個計數(shù)器峻汉,然后依次讀取每一個位置的元素贴汪,當讀取到最后一個元素后,停止休吠。主要就是需要按元素的位置來讀取元素扳埂。
2、迭代器遍歷瘤礁,Iterator:
每一個具體實現(xiàn)的數(shù)據(jù)集合阳懂,一般都需要提供相應(yīng)的Iterator。相比于傳統(tǒng)for循環(huán),Iterator取締了顯式的遍歷計數(shù)器岩调。所以基于順序存儲集合的Iterator可以直接按位置訪問數(shù)據(jù)克饶。而基于鏈式存儲集合的Iterator,正常的實現(xiàn)誊辉,都是需要保存當前遍歷的位置矾湃。然后根據(jù)當前位置來向前或者向后移動指針。
3堕澄、foreach循環(huán)遍歷:
根據(jù)反編譯的字節(jié)碼可以發(fā)現(xiàn)邀跃,foreach內(nèi)部也是采用了Iterator的方式實現(xiàn),只不過Java編譯器幫我們生成了這些代碼蛙紫。

各遍歷方式的適用于什么場合拍屑?

1、傳統(tǒng)的for循環(huán)遍歷坑傅,基于計數(shù)器的:
順序存儲:讀取特定元素平均時間復(fù)雜度是O(1)僵驰,遍歷則只需平均時間復(fù)雜度是O(n)。因此讀取性能比較高唁毒。適用于遍歷順序存儲集合蒜茴。
鏈式存儲:查找特定元素平均時間復(fù)雜度是O(n),遍歷則只需平均時間復(fù)雜度是O(n^2)浆西。因此時間復(fù)雜度太大粉私,不適用于遍歷鏈式存儲的集合。
2近零、迭代器遍歷诺核,Iterator:
順序存儲:增加了額外的操作,額外的運作時間久信,沒有太大的意義窖杀。若想要代碼更加簡潔,可以使用裙士。
鏈式存儲:因為Iterator內(nèi)部維護了當前遍歷的位置入客,使查找特定元素(移動指針指向下一個)的平均時間復(fù)雜度降為O(n),即總遍歷的平均時間復(fù)雜度降為O(n)潮售。因此所以推薦此種遍歷方式痊项。
3、foreach循環(huán)遍歷:
foreach能使代碼更加簡潔了酥诽,但是它有一些缺點鞍泉,就是遍歷過程中不能操作數(shù)據(jù)集合(刪除等),所以有些場合不使用肮帐。其本身就是基于Iterator實現(xiàn)的咖驮,由于類型轉(zhuǎn)換的問題边器,所以會比直接使用Iterator慢一點,但是還好托修,時間復(fù)雜度都是一樣的忘巧。

Java的最佳實踐是什么?

Java數(shù)據(jù)集合框架中睦刃,提供了一個RandomAccess接口砚嘴,該接口沒有方法,只是一個標記涩拙。通常被List接口的實現(xiàn)使用际长,用來標記該List的實現(xiàn)是否支持Random Access。
一個數(shù)據(jù)集合實現(xiàn)了該接口兴泥,就意味著它支持Random Access工育,按位置讀取元素的平均時間復(fù)雜度為O(1)。比如ArrayList搓彻。
而沒有實現(xiàn)該接口的如绸,就表示不支持Random Access。比如LinkedList旭贬。
所以看來JDK開發(fā)者也是注意到這個問題的怔接,那么推薦的做法就是,如果想要遍歷一個List骑篙,那么先判斷是否支持Random Access蜕提,也就是 list instanceof RandomAccess森书。
比如:

if (list instanceof RandomAccess) {
    //順序存儲結(jié)構(gòu)靶端,使用傳統(tǒng)的for循環(huán)遍歷。
} else {
    //非順序存儲結(jié)構(gòu)凛膏,使用Iterator或者foreach杨名。
}

參考文章:https://www.cnblogs.com/leskang/p/6031282.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市猖毫,隨后出現(xiàn)的幾起案子台谍,更是在濱河造成了極大的恐慌,老刑警劉巖吁断,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趁蕊,死亡現(xiàn)場離奇詭異,居然都是意外死亡仔役,警方通過查閱死者的電腦和手機掷伙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來又兵,“玉大人任柜,你說我怎么就攤上這事卒废。” “怎么了宙地?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵摔认,是天一觀的道長。 經(jīng)常有香客問我宅粥,道長参袱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任秽梅,我火速辦了婚禮蓖柔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘风纠。我一直安慰自己况鸣,他們只是感情好,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布竹观。 她就那樣靜靜地躺著镐捧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪臭增。 梳的紋絲不亂的頭發(fā)上懂酱,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音誊抛,去河邊找鬼列牺。 笑死,一個胖子當著我的面吹牛拗窃,可吹牛的內(nèi)容都是我干的瞎领。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼随夸,長吁一口氣:“原來是場噩夢啊……” “哼九默!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起宾毒,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤驼修,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后诈铛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乙各,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年幢竹,在試婚紗的時候發(fā)現(xiàn)自己被綠了耳峦。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡妨退,死狀恐怖妇萄,靈堂內(nèi)的尸體忽然破棺而出蜕企,到底是詐尸還是另有隱情,我是刑警寧澤冠句,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布轻掩,位于F島的核電站,受9級特大地震影響懦底,放射性物質(zhì)發(fā)生泄漏唇牧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一聚唐、第九天 我趴在偏房一處隱蔽的房頂上張望丐重。 院中可真熱鬧,春花似錦杆查、人聲如沸扮惦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽崖蜜。三九已至,卻和暖如春客峭,著一層夾襖步出監(jiān)牢的瞬間豫领,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工舔琅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留等恐,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓备蚓,卻偏偏與公主長得像课蔬,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子星著,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

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

  • 概述 Java語言中购笆,提供了一套數(shù)據(jù)集合框架,其中定義了一些諸如List虚循、Set等抽象數(shù)據(jù)類型,每個抽象數(shù)據(jù)類型的...
    一天一夜00閱讀 676評論 0 2
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法样傍,類相關(guān)的語法横缔,內(nèi)部類的語法,繼承相關(guān)的語法衫哥,異常的語法茎刚,線程的語...
    子非魚_t_閱讀 31,639評論 18 399
  • 阿瞳是個沒什么大志向的青年。高中畢業(yè)撤逢,他突發(fā)奇想膛锭,在街上擺了個烤串攤粮坞,想掙幾個煙錢,順便打發(fā)打發(fā)時間初狰。 攤子擺在帝...
    簡詩歌閱讀 298評論 0 3
  • 突然蹦噠到你身邊發(fā)問 “你愛不愛我莫杈?” “唔…不愛…”你摸著我的頭壞笑著說。我笑嘻嘻...
    世界末日的早上閱讀 150評論 0 2
  • 1.音頻奢入,peppa pig循環(huán)筝闹,史記, 2.視頻腥光,無 3.游戲和拓展关顷,在飛機上玩了幾個清英小游戲,where i...
    紫夜1606閱讀 102評論 0 0