Java Iterator迭代器與foreach循環(huán)代碼解析
一、 Iterator迭代器接口
1. 使用 Iterator 接口遍歷集合元素
?
Iterator
對(duì)象稱為迭代器(設(shè)計(jì)模式的一種),主要用于遍歷Collection
集合中的元素。
?
GOF
給迭代器模式的定義為:提供一種方法訪問(wèn)一個(gè)容器(container
)對(duì)象中各個(gè)元素,而又不需暴露該對(duì)象的內(nèi)部細(xì)節(jié)。迭代器模式,就是為容器而生。類似于“公交車上的售票員”、“火車上的乘務(wù)員”、“空姐”。
?
Collection
接口繼承了java.lang.Iterable
接口,該接口有一個(gè)iterator()
方法,那么所有實(shí)現(xiàn)了Collection
接口的集合類都有一個(gè)iterator()
方法,用以返回一個(gè)實(shí)現(xiàn)了Iterator
接口的對(duì)象。
?
Iterator
僅用于遍歷集合,Iterator
本身并不提供承裝對(duì)象的能力。如果需要?jiǎng)?chuàng)建Iterator
對(duì)象,則必須有一個(gè)被迭代的集合。
?集合對(duì)象每次調(diào)用
iterator()
方法都得到一個(gè)全新的迭代器對(duì)象,默認(rèn)游標(biāo)都在集合 的第一個(gè)元素之前。
2. Iterator接口的方法
注意:在調(diào)用
it.next()
方法之前必須要調(diào)用it.hasNext()
進(jìn)行檢測(cè)。若不調(diào)用,且下一條記錄無(wú)效,直接調(diào)用it.next()
會(huì)拋出NoSuchElementException
異常。
3. 迭代器的執(zhí)行原理
3.1 代碼演示
//hasNext():判斷是否還有下一個(gè)元素 while(iterator.hasNext()){ //next():①指針下移 ②將下移以后集合位置上的元素返回 System.out.println(iterator.next()); }
3.2 代碼執(zhí)行過(guò)程解析
當(dāng)執(zhí)行
Iterator iterator = coll.iterator();
語(yǔ)句時(shí),iterator
的指針此時(shí)執(zhí)行下圖的①所標(biāo)的位置,然后執(zhí)行iterator.hasNext()
語(yǔ)句,此時(shí)會(huì)去判斷iterator
的指針指向的位置的下一個(gè)位置(即②)有無(wú)元素,若有,則返回true
,否則返回false
。當(dāng)返回結(jié)果為true
時(shí),則往下執(zhí)行iterator.next()
語(yǔ)句,此時(shí)iterator
的指針下移并且把下移后的指針指向的集合位置上的元素返回。
4. Iterator接口remove()方法
4.1 代碼演示
Iterator iter = coll.iterator();//回到起點(diǎn) while(iter.hasNext()){ Object obj = iter.next(); if(obj.equals("Tom")){ iter.remove(); } }
4.2 注意
?
Iterator
可以刪除集合的元素,但是是遍歷過(guò)程中通過(guò)迭代器對(duì)象的remove
方法,不是集合對(duì)象的remove
方法。
? 如果還未調(diào)用
next()
或在上一次調(diào)用next()
方法之后已經(jīng)調(diào)用了remove
方法,再調(diào)用remove
都會(huì)報(bào)IllegalStateException
異常。
5. 代碼演示
@Test public void test1(){ Collection coll = new ArrayList(); coll.add(123); coll.add(456); coll.add(new Person("Jerry",20)); coll.add(new String("Tom")); coll.add(false); Iterator iterator = coll.iterator(); //方式一: // System.out.println(iterator.next()); // //報(bào)異常:NoSuchElementException //方式二:不推薦 // for(int i = 0;i < coll.size();i++){ // System.out.println(iterator.next()); // } //方式三:推薦 hasNext():判斷是否還有下一個(gè)元素 while(iterator.hasNext()){ //next():①指針下移 ②將下移以后集合位置上的元素返回 System.out.println(iterator.next()); } }
@Test public void test2(){ Collection coll = new ArrayList(); coll.add(123); coll.add(456); coll.add(new Person("Jerry",20)); coll.add(new String("Tom")); coll.add(false); //錯(cuò)誤方式一: // Iterator iterator = coll.iterator(); // while((iterator.next()) != null){ // System.out.println(iterator.next()); // } //錯(cuò)誤方式二: //集合對(duì)象每次調(diào)用iterator()方法都得到一個(gè)全新的迭代器對(duì)象,默認(rèn)游標(biāo)都在集合的第一個(gè)元素之前。 while (coll.iterator().hasNext()){ System.out.println(coll.iterator().next()); } } //測(cè)試Iterator中的remove() //如果還未調(diào)用next()或在上一次調(diào)用 next 方法之后已經(jīng)調(diào)用了 remove 方法, // 再調(diào)用remove都會(huì)報(bào)IllegalStateException。
@Test public void test3(){ Collection coll = new ArrayList(); coll.add(123); coll.add(456); coll.add(new Person("Jerry",20)); coll.add(new String("Tom")); coll.add(false); //刪除集合中"Tom" Iterator iterator = coll.iterator(); while (iterator.hasNext()){ // iterator.remove(); Object obj = iterator.next(); if("Tom".equals(obj)){ iterator.remove(); // iterator.remove(); } } //遍歷集合 iterator = coll.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } }
二、foreach 循環(huán)
1. 概述
?
Java 5.0
提供了foreach
循環(huán)迭代訪問(wèn)Collection
和數(shù)組。
? 遍歷操作不需獲取
Collection
或數(shù)組的長(zhǎng)度,無(wú)需使用索引訪問(wèn)元素。
? 遍歷集合的底層調(diào)用
Iterator
完成操作。
?
foreach
還可以用來(lái)遍歷數(shù)組。
2. 語(yǔ)法解析
3. 代碼演示
@Test public void test1(){ Collection coll = new ArrayList(); coll.add(123); coll.add(456); coll.add(new Person("Jerry",20)); coll.add(new String("Tom")); coll.add(false); //for(集合元素的類型 局部變量 : 集合對(duì)象) //內(nèi)部仍然調(diào)用了迭代器。 for(Object obj : coll){ System.out.println(obj); } //123 //456 //Person@621be5d1 //Tom //false }
@Test public void test2(){ int[] arr = new int[]{1,2,3,4,5,6}; //for(數(shù)組元素的類型 局部變量 : 數(shù)組對(duì)象) for(int i : arr){ System.out.println(i); } //1 //2 //3 //4 //5 //6 }
4. 易錯(cuò)題
public class test { public static void main(String[] args) { String[] str = new String[5]; for (String myStr : str) { myStr = "小老師ir"; System.out.println(myStr); } //小老師ir //小老師ir //小老師ir //小老師ir //小老師ir for (int i = 0; i < str.length; i++) { System.out.println(str[i]); } //null //null //null //null //null } }
到此這篇關(guān)于Java-Iterator迭代器與foreach循環(huán)的文章就介紹到這了,更多相關(guān)Java Iterator迭代器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java線程之用Thread類創(chuàng)建線程的方法
本篇文章介紹了,Thread類創(chuàng)建線程的方法。需要的朋友參考下2013-05-05java 實(shí)現(xiàn)圖片圓角處理、背景透明化
這篇文章主要介紹了java 實(shí)現(xiàn)圖片圓角處理、背景透明化,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11Java中字符串常見(jiàn)的一些拼接方式總結(jié)
字符串拼接是我們?cè)贘ava代碼中比較經(jīng)常要做的事情,就是把多個(gè)字符串拼接到一起,下面這篇文章主要給大家總結(jié)介紹了關(guān)于Java中字符串常見(jiàn)的一些拼接方式,需要的朋友可以參考下2023-04-04Spark學(xué)習(xí)筆記之Spark中的RDD的具體使用
這篇文章主要介紹了Spark學(xué)習(xí)筆記之Spark中的RDD的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06SpringBoot項(xiàng)目中Controller接收兩個(gè)實(shí)體的實(shí)現(xiàn)方法
本文主要介紹了SpringBoot項(xiàng)目中Controller接收兩個(gè)實(shí)體的實(shí)現(xiàn)方法,主要介紹了兩種方法,具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08Java特性?Lambda?表達(dá)式和函數(shù)式接口
這篇文章主要介紹了Java特性?Lambda?表達(dá)式和函數(shù)式接口,Lambda表達(dá)式基于函數(shù)式編程思想,也可以稱為閉包,是Java?8引入的重要新特性,?Lambda允許把函數(shù)作為一個(gè)方法的參數(shù)2022-06-06java中實(shí)現(xiàn)map與對(duì)象相互轉(zhuǎn)換的幾種實(shí)現(xiàn)
這篇文章主要介紹了java中實(shí)現(xiàn)map與對(duì)象相互轉(zhuǎn)換的幾種實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07