Java迭代器與Collection接口超詳細(xì)講解
關(guān)于迭代器你都知道什么?
什么是迭代器?
所謂迭代的意思就是交換替代,迭代器并不是一種數(shù)據(jù)結(jié)構(gòu)或者集合,而是可以過迭代器中的方法逐個(gè)訪問集合中的每個(gè)元素的一種方法。提到迭代器最重要的就是Iterator接口,所有想要使用迭代器迭代的結(jié)構(gòu)都需要實(shí)現(xiàn)或者繼承這個(gè)接口
迭代器的4個(gè)API
Iterator接口包含4個(gè)方法,分別是next、hasNext、remove、forEachRemaining,接下來在學(xué)習(xí)構(gòu)造器如何使用之前我們先學(xué)習(xí)一下它的四種方法
首先一開始構(gòu)造器中的有一個(gè)類似于指針的標(biāo)志,指在集合中第一個(gè)元素的前面,調(diào)用構(gòu)器中的next方法會(huì)使這個(gè)"指針"的位置后移到第一和二個(gè)元素之間,然后返回它跨過的那個(gè)元素給構(gòu)造器,也就是第一個(gè)元素,如果"指針"到最后一個(gè)元素后面再調(diào)用next方法的話就會(huì)導(dǎo)致拋出NoSuchElementException
remove方法則是刪除當(dāng)前元素,可以理解為next方法返回的那個(gè)元素,如果調(diào)用remove方法之前沒有調(diào)用next方法或者是使用remove方法刪除該元素之后都會(huì)導(dǎo)致構(gòu)造器為空,此時(shí)調(diào)用remove方法就會(huì)導(dǎo)致程序拋出IllegalStateExceptions異常
hasNext方法就是判斷迭代器是否還有可迭代的下一個(gè)元素,如果有的話就返回true否則返回false,為了避免上述兩種異常,remove方法每次都要配合另外兩種方法一起使用,每次調(diào)用next方法之前都使用hasNext方法判斷一下,避免沒有可迭代元素導(dǎo)致的異常,每一次調(diào)用remove之前都使用next方法獲得元素,避免迭代器為空導(dǎo)致的狀態(tài)異常
forEachRemaining方法則可以直接遍歷迭代器中的每一個(gè)元素并調(diào)用方法參數(shù)中的Lambda表達(dá)式,直到迭代器將集合的元素全部迭代完為止
如何使用迭代器?
接下來將結(jié)合上面的描述給出一個(gè)將集合中的元素全部刪除的標(biāo)準(zhǔn)代碼,然后再給出兩個(gè)錯(cuò)誤的代碼,大家可以在使用迭代器的時(shí)候規(guī)避一下
正確寫法
// 創(chuàng)建一個(gè)ArrayList集合 Collection<String> strings = new ArrayList<>(); strings.add("a"); strings.add("b"); strings.add("c"); strings.add("d"); // 獲得迭代器對(duì)象 Iterator<String> iterator = strings.iterator(); // 使用while循環(huán)迭代集合中元素 使用hasNext方法判斷 while (iterator.hasNext()) { // 使用next獲取下一個(gè)元素 iterator.next(); // 刪除這個(gè)元素 iterator.remove(); // 打印集合中元素 System.out.println(strings); }
錯(cuò)誤示范一
// 創(chuàng)建一個(gè)ArrayList集合 Collection<String> strings = new ArrayList<>(); strings.add("a"); strings.add("b"); strings.add("c"); strings.add("d"); // 獲得迭代器 Iterator<String> iterator = strings.iterator(); // 使用while循環(huán)迭代集合中元素 使用next方法判斷下一個(gè)元素是否為空 while (iterator.next() != null) { // 輸出這個(gè)元素 System.out.println(iterator.next()); }
第一個(gè)的錯(cuò)誤原因:使用next方法判斷下一個(gè)元素是否為空,這樣就會(huì)導(dǎo)致"指針"到最后一個(gè)元素后面依舊會(huì)執(zhí)行next方法,這樣就會(huì)導(dǎo)致拋出NoSuchElementException異常;而且next方法每調(diào)用一次都會(huì)將"指針"向后移動(dòng)一位,哪怕只是用于if判斷。所以程序就會(huì)每隔一個(gè)元素輸出一次,最后拋出NoSuchElementException異常
錯(cuò)誤示范二
// 創(chuàng)建一個(gè)ArrayList集合 Collection<String> strings = new ArrayList<>(); strings.add("a"); strings.add("b"); strings.add("c"); strings.add("d"); // 獲取迭代器對(duì)象 并使用while循環(huán)迭代集合中元素 使用hasNext方法判斷 while (strings.iterator().hasNext()) { // 獲取迭代器對(duì)象 并使用next獲取下一個(gè)元素 然后輸出 System.out.println(strings.iterator().next()); }
第二個(gè)的錯(cuò)誤原因:每使用iterator方法獲得一次集合對(duì)應(yīng)的迭代器對(duì)象,都會(huì)默認(rèn)將"指針"放到第一個(gè)元素的前面,于是第二個(gè)錯(cuò)誤示范中一直使用集合中的第一個(gè)元素"a"進(jìn)行判斷有沒有下一個(gè)元素,所以會(huì)導(dǎo)致程序陷入死循環(huán),循環(huán)體里也會(huì)一直創(chuàng)建結(jié)合的迭代器對(duì)象,并將"指針"放到第一個(gè)元素的前面,然后調(diào)用next方法輸出元素"a"
Collection集合接口知多少?
集合大體上可以分為兩種,一種是單列的Collection集合,一種就是雙列的Map集合,所謂的單雙列可以理解為元素中數(shù)據(jù)的個(gè)數(shù),單列集合一個(gè)數(shù)據(jù)作為元素存儲(chǔ),雙列集合兩個(gè)具有映射關(guān)系的數(shù)據(jù)作為元素存儲(chǔ)。這一篇我們先學(xué)習(xí)Collection集合接口的內(nèi)容,Collection集合按照元素存儲(chǔ)是否有序又可分為L(zhǎng)ist集合、Set集合
前面之所以先學(xué)習(xí)Iterator接口的原因就是,Collection接口繼承了Iteator接口,于是它的子接口set和list都可以使用迭代器對(duì)集合中的元素進(jìn)行迭代
為什么不使用數(shù)組而是集合?
在學(xué)習(xí)集合之前,我們將存儲(chǔ)多個(gè)對(duì)象或者元素的任務(wù)都交給了數(shù)組,但是數(shù)組存儲(chǔ)元素有以下缺點(diǎn):
①數(shù)組一旦初始化之后,長(zhǎng)度就確定不可修改,元素個(gè)數(shù)超出數(shù)組長(zhǎng)度的話會(huì)拋異常。
②數(shù)組中提供的API很少,增加元素需要現(xiàn)將索引后的元素后移空出位置將元素添加進(jìn)去,刪除元素需要?jiǎng)h除之后將后面的元素前移將空出來的位置補(bǔ)足,以上操作只能通過代碼實(shí)現(xiàn)并沒有現(xiàn)成的API可以使用。
③數(shù)組存儲(chǔ)數(shù)據(jù)的特點(diǎn):有序、可重復(fù),對(duì)于一些無需、不可重復(fù)的業(yè)務(wù)需求就很難滿足
集合就可以很好的彌補(bǔ)數(shù)組的上述缺點(diǎn),而且集合提供了一組較為完善的數(shù)據(jù)結(jié)構(gòu),我們可以根據(jù)具體的業(yè)務(wù)需求來選擇具體使用的集合類型。比如說存儲(chǔ)元素?zé)o序不可重復(fù)的Set集合,有序可重復(fù)的List集合,具有映射關(guān)系的Map集合等
Collection接口的API都有什么?
AbstractCollection類知多少?
以上給出的Collection接口中的API都是抽象方法,也就意味著每一個(gè)此接口的實(shí)現(xiàn)類都需要重寫這些抽象方法,實(shí)際上Collection接口的直接或者間接實(shí)現(xiàn)類有很多,如果每一個(gè)都需要重寫這些方法的話就會(huì)很是麻煩。于是Java類庫的設(shè)計(jì)者提供了AbstractCollection類,該類中只將size方法和Iterator方法聲明為抽象,其他方法都提供了默認(rèn)實(shí)現(xiàn),如果子類不提供這些方法的方法體的話就使用該類中的默認(rèn)實(shí)現(xiàn)
下圖可知,list、set集合的實(shí)現(xiàn)類都直接或者間接的繼承了AbstractCollection類,為的就是簡(jiǎn)化重寫Collection接口的抽象方法
到此這篇關(guān)于Java迭代器與Collection接口超詳細(xì)講解的文章就介紹到這了,更多相關(guān)Java迭代器與Collection接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何使用Spring Cloud Feign日志查看請(qǐng)求響應(yīng)
這篇文章主要介紹了如何使用Spring Cloud Feign日志查看請(qǐng)求響應(yīng),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02IDEA無法打開Marketplace的三種解決方案(推薦)
這篇文章主要介紹了IDEA無法打開Marketplace的三種解決方案(推薦),本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11MyBatis各種類型查詢數(shù)據(jù)參數(shù)綁定的實(shí)現(xiàn)
本文主要介紹了MyBatis各種類型查詢數(shù)據(jù)參數(shù)綁定的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06JAVA實(shí)現(xiàn)簡(jiǎn)單搶紅包算法(模擬真實(shí)搶紅包)
這篇文章主要介紹了JAVA實(shí)現(xiàn)簡(jiǎn)單搶紅包算法(模擬真實(shí)搶紅包)的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12SpringBoot文件上傳與下載功能實(shí)現(xiàn)詳解
文件上傳與下載是Web應(yīng)用開發(fā)中常用的功能之一。接下來我們將討論如何在Spring?Boot的Web應(yīng)用開發(fā)中,如何實(shí)現(xiàn)文件的上傳與下載,感興趣的可以了解一下2022-10-10Java使用非覆蓋的方法實(shí)現(xiàn)替換PDF中的文本
這篇文章主要為大家詳細(xì)介紹了Java如何使用非覆蓋的方法實(shí)現(xiàn)替換PDF中的文本,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-02-02Java?棧與隊(duì)列實(shí)戰(zhàn)真題訓(xùn)練
在編寫程序的時(shí)候,對(duì)于棧與隊(duì)列的應(yīng)用需要熟練的掌握,這樣才能夠確保寫出來的代碼有質(zhì)量。本文小編就以幾個(gè)題目詳細(xì)說說Java中的棧與隊(duì)列,需要的朋友可以參考一下2022-04-04freemarker簡(jiǎn)介_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
FreeMarker是一個(gè)模板引擎,一個(gè)基于模板生成文本輸出的通用工具,使用純Java編寫,有興趣的可以了解一下2017-08-08