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