摘要:迭代器通常被成為輕量級對象創(chuàng)建它的代價很小。與迭代器可以用于數(shù)組和所有對象,之所以能夠工作,是因為繼承了接口。
點擊進(jìn)入我的博客
我覺得本章名字改成容器似乎更好理解,持有對象讓人感到一頭霧水
我們需要在任意時刻和任意位置創(chuàng)建任意數(shù)量的對象,所以依靠創(chuàng)建命名的引用來持有對象已經(jīng)滿足不了需求。
Java可以用數(shù)組和其他容器類來(List、Set、Queue、Map)來解決這個問題,不同的容器類有各自的特性,滿足不同的需求。
Java SE5之前是沒有范型的,一個容器內(nèi)(以List為例)可以放置任意的對象。
public class Test { // 用@SuppressWarnings抑制編譯器對“不受檢查的異?!钡木? @SuppressWarnings("unchecked") public static void main(String[] args) { // (1) List strList = new ArrayList() { { add("spidersama"); add(520); } }; // (2) for (Object obj : strList) { System.out.println(((String) obj).length()); } } }
如上所示,(1)處的代碼在編譯和運行的時候都沒有任何問題;但是當(dāng)你在(2)處需要把Object類型強(qiáng)制轉(zhuǎn)型成你需要的對象類型的時候,這個時候就會出現(xiàn)問題,因為Integer是無法轉(zhuǎn)型成String類型的。
所以更安全的做法是,我們在創(chuàng)建一個容器的時候就明確它能存放的類型是什么List
編譯器將阻止我們放置其他類型的對象;
而且你在從容器中取出對象的時候,也不必在強(qiáng)制轉(zhuǎn)型,因為List知道你需要的對象類型是什么,它將會幫你自動轉(zhuǎn)型。
我們可以將聲明類型的子類放入該容器(即子類的向上轉(zhuǎn)型)。
11.2 基本概念Java容器類類庫的用途是“保存對象”,并將其劃分為兩個不同的概念。
Collection:一個獨立元素的序列。所有Collection都可以用foreach遍歷。
Map:一組成對的“鍵值對”對象,允許你使用鍵來查找值。
11.3 添加一組元素Arrays.asList();
Collections.addAll();
collection.addAll();
Collection的構(gòu)造器可以接受一個Collection來初始化
Collectioncollection = new ArrayList<>(Arrays.asList(1, 2, 3)); collection.addAll(Arrays.asList(new Integer[]{1, 2, 3})); Arrays.asList(new int[]{1, 2, 3}); Arrays.asList(1, 2, 3); Collections.addAll(collection, new Integer[]{1, 2, 3}); Collections.addAll(collection, 1, 2, 3);
注意:Arrays.asList()返回的ArrayList不可以添加元素,此ArrayList和java.util.ArrayList不是同一個類。
11.4 容器的打印如果你要打印一個數(shù)組,需要用Arrays.toString()方法,直接打印數(shù)組顯示的是[I@61bbe9ba這種之前介紹過的格式。
容器由于重寫了toString()方法,所以可以直接打印出可讀性強(qiáng)的結(jié)果。
由于不同Collection或Map的子類元素放置的規(guī)則和順序不同,所以向容器內(nèi)添加相同的元素,打印的結(jié)果不一定相同。
HashMap提供了最快的查找技術(shù),沒有任何明顯的順序來保存其元素;TreeMap按照比較結(jié)果的升序保存鍵;LinkedHashMap按照插入順序保存鍵,同時還保留了HashMap的查詢速度。
11.5 ListList是一種可修改的序列,它允許在創(chuàng)建之后添加、移除元素,或者自我調(diào)整尺寸。
基本的ArrayList,它擅長隨機(jī)訪問元素,但是在List的中間插入和刪除元素時較慢
LinkedList,它通過代價較低的方式在List中進(jìn)行插入和刪除操作,提供了優(yōu)化的順序訪問;但是隨機(jī)訪問方面相對較慢。
迭代器是一個對象,他的工作是遍歷并選擇序列中的對象,而程序員不必知道該序列的底層結(jié)構(gòu),即將遍歷序列的操作和序列底層的結(jié)構(gòu)分離。
迭代器通常被成為輕量級對象:創(chuàng)建它的代價很小。
Java的迭代器只能向前移動
使用方法iterator()要求容器返回一個Iterator,Iterator準(zhǔn)備好返回序列的第一個元素
使用next()獲取序列中的下一個元素
使用hasNext()檢查序列中是否還有元素
使用remove()將迭代器新近返回的元素刪除
它是Iterator的子類型,只能用于List的訪問。
它可以雙向移動
它可以返回當(dāng)前位置前一個元素和后一個元素的索引(即下標(biāo))
可使用時set()方法替換訪問過的最近的元素
可以使用listIterator(int index)直接創(chuàng)建一個指向索引處的ListIterator
11.7 LinkedList如前所述,LinkedList也像ArrayList一樣實現(xiàn)了基本的List接口,但是它執(zhí)行插入和移除時比ArrayList要更高效,但是在隨機(jī)訪問操作方面要慢。
LinkedList還添加了可以使其用作棧、隊列或雙端隊列的方法(是Queue的子類)。
正是由于LinkedList添加了棧和隊列的方法,使得內(nèi)部多了一些功能相同但名稱不同(為了覆蓋父類)的方法
getFirst() == element() ≈ peek():都是返回第一個元素,但是在空List的時候處理不一樣
removeFirst() == remove() ≈ poll():都是移除并返回列表的頭,但是在空List的時候處理不一樣
addFirst() == addLast():都將某個元素插入隊尾
11.8 Stack 棧棧是一種先進(jìn)后出(Last In First Out,LIFO)的容器(數(shù)據(jù)結(jié)構(gòu))。
LinkedList能實現(xiàn)棧所有的功能。
peek():返回棧頂元素
pop():返回并移除棧頂元素
push():元素入棧
empty():棧是否為空
11.9 Set 集合Set不保存重復(fù)的元素。
Set與Collection有完全一樣的接口(方法),因此沒有任何額外的功能,實際上Set就是Collection只是行為不同(這就是繼承和多態(tài)思想的典型應(yīng)用:體現(xiàn)不同的行為)。
HashSet:使用的是散列函數(shù)
TreeSet:將元素存儲在紅-黑樹數(shù)據(jù)結(jié)構(gòu)中。TreeSet默認(rèn)是按照字典序排序的;初始化TreeSet的時候可以設(shè)定排序的方式,如String.CASE_INSENSITIVE_ORDER就是按照字母序排列;你也可以寫一個你自己的比較器Comparator。
LinkedHashSet:是HashSet的擴(kuò)展,但是元素順序是按照放插入順序保存的。
11.10 Map鍵值對
11.11 Queue 隊列隊列是一個典型的先進(jìn)先出(First In First Out,F(xiàn)IFO)的容器。
隊列通常被當(dāng)作一種可靠的將對象從程序的一個區(qū)域傳輸?shù)搅硪粋€區(qū)域的途徑,尤其在并發(fā)編程中十分重要。
offer():將元素插入隊尾。
add():同offer(),但是當(dāng)超出隊列長度當(dāng)時候拋出異常。
peek():不移除的返回隊頭元素;為空時返回null。
element():同peek(),為空時拋出NoSuchElementException。
poll():移除并返回隊頭元素,為空時返回null。
remove():同poll(),為空時拋出NoSuchElementException異常。
11.11.1 PriorityQueue優(yōu)先級隊列:按照優(yōu)先級的順序維護(hù)的隊列。
當(dāng)你在PriorityQueue上調(diào)用offer()方法來插入一個對象時,這個對象會在隊列中被排序。默認(rèn)的排序?qū)⑹褂脤ο笤陉犃兄凶匀豁樞?,但是你可以通過提供自己的Comparator來修改這個順序。PriorityQueue可以確保當(dāng)你調(diào)用相關(guān)方法時,獲取的元素將是隊列中優(yōu)先級最高的元素。
Java中,實現(xiàn)Collection就必須提供iterator()方法,這有的時候會帶來麻煩。
直接生成Iterator是將隊列與消費隊列的方法鏈接在一起耦合度最小的方式,并且與實現(xiàn)Collection相比,它在序列類上所施加的約束也少得多。
foreach可以用于數(shù)組和所有Collection對象,之所以能夠工作,是因為Collection繼承了Iterable接口。
數(shù)組不是Iterable。
Iterable接口包含一個能夠產(chǎn)生Iterator的iterator()方法,并且Iterable接口被foreach用來在序列中移動。換言之,任何實現(xiàn)了Iterable接口的類,都可以用與foreach語法。
如果需要多個foreach遍歷一個類的方法,例如該類需要支持向前和向后遍歷。這是只實現(xiàn)Iterable是不行的,可以編寫其他返回類型為Iterable的方法來滿足foreach語句。這就是編寫適配器。
// 反向遍歷部分代碼 public class Test10.14 總結(jié)extends ArrayList { public Test(Collection extends E> c) { super(c); } public Iterable reverse() { return new Iterable () { @Override public Iterator iterator() { return new Iterator () { int index = size() - 1; @Override public boolean hasNext() { return index >= 0; } @Override public E next() { return get(index--); } }; } }; } }
數(shù)組將數(shù)字與對象聯(lián)系起來。
Collection保存單一的元素,而Map保存相關(guān)聯(lián)的鍵值對。
List也建立數(shù)字索引與對象的關(guān)聯(lián),List能夠自動擴(kuò)充容量。
如果要進(jìn)行大量的隨機(jī)訪問,就使用ArrayList;如果要經(jīng)常從表中間出入或刪除元素,則應(yīng)該使用LinkedList。
各種Queue以及棧的行為,由LinkedList提供支持。
Map是一種將對象(而非數(shù)字)與對象相關(guān)聯(lián)的設(shè)計。HashMap設(shè)計用來快速訪問;而TreeMap保持“鍵”始終處于排序狀態(tài),所以沒有HashMap快。LinkedHashMap保持元素插入的順序,但是也通過散列提供了快速訪問能力。
Set不接受重復(fù)元素。HashSet提供最快的查詢速度,而TreeSet保持元素處于排序狀態(tài),LinkedHashSet以插入順序保存元素。
不要使用已過時的Vector、Hashtable和Stack。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/72195.html
摘要:前言編程思想這本書,陸陸續(xù)續(xù)讀了年,終于基本都瀏覽了一遍。每個對象對外暴露接口,程序通過對象暴露的接口向?qū)ο蟀l(fā)送消息,獲取該對象的服務(wù)能力。異常處理異常處理,為編寫程序階段提供了一種預(yù)見性的防止程序崩潰的出路。 前言 《Java編程思想》這本書,陸陸續(xù)續(xù)讀了1年,終于基本都瀏覽了一遍。通過這本書,試圖理解作者的想法,才真的體會到Java思想。感謝本書的作者,不僅講述了java的語法,更...
摘要:方法接受一個對象,以及一個數(shù)組或是一個用逗號分隔的列表,并將元素添加到中。工作的很好,因為他從第一個參數(shù)中了解到了目標(biāo)類型是什么。 ArrayList.asList() 接受一個數(shù)組或是用逗號分隔的元素列表,也可以用可變參數(shù),然后將其轉(zhuǎn)為一個List對象。 Collections.addAll()方法接受一個Collection對象,以及一個數(shù)組或是一個用逗號分隔的列表,并將元素添加...
Java是面向?qū)ο蟮恼Z言,對象時Java不可或缺的一個元素,基本數(shù)據(jù)類型有數(shù)組用來存儲,那么對象元素有什么存儲呢,這就是集合,集合是Java非常重要的一塊知識,Java編程思想中的持有對象簡述了集合的相關(guān)知識,下面簡述集合的相關(guān)功能: showImg(/img/bVC153); 集合類我們通常稱為容器 其實容器只有四種:Map、List、Set和Queue 常用的容器有ArrayList、Lin...
摘要:概述容器類類庫的用途是保存對象,它分為兩個不同的概念這是一個獨立的而序列必須按照插入的順序保存元素不能有重復(fù)元素按照排隊規(guī)則來確定對象產(chǎn)生的順序由鍵值對組成的,允許由鍵查找值,就像字典的目錄,根據(jù)目錄查找內(nèi)容創(chuàng)建接口的不同形式對象時具體的, 概述 Java容器類類庫的用途是保存對象,它分為兩個不同的概念: Collection:這是一個獨立的而序列 List必須按照插入的順序保存...
摘要:層次結(jié)構(gòu)如上所示,的子類都可以作為集合的元素加入到集合中,并且不會有任何影響。在實際編碼中一般都建議使用類型安全的容器,這樣不容易出錯,出錯也會在編譯期間就會展現(xiàn)出來。 概述 說起類型安全的容器,那么什么是類型不安全的容器呢?容器用來存儲數(shù)據(jù),常見的存儲數(shù)據(jù)的容器有數(shù)組和集合,數(shù)組有以下特點: 長度固定 只能存儲同一種類型的數(shù)據(jù) 因為數(shù)組只能存儲同一種數(shù)據(jù)類型的數(shù)據(jù),那么它就是類型...
閱讀 1353·2023-04-26 01:03
閱讀 1999·2021-11-23 09:51
閱讀 3360·2021-11-22 15:24
閱讀 2713·2021-09-22 15:18
閱讀 1055·2019-08-30 15:55
閱讀 3605·2019-08-30 15:54
閱讀 2359·2019-08-30 15:53
閱讀 2433·2019-08-30 15:44