java之增強(qiáng)for和迭代器精選

2022-12-19 10:13:30 來源:51CTO博客

前言:

未來這個(gè)詞聽上去就是美好,可是你別忘了呀,每一個(gè)我們所期待的美好未來,都必須有一個(gè)努力的現(xiàn)在?。。?

我們上一篇聊到了java之集合,這一篇我們聊一下增強(qiáng)for和迭代器,針對(duì)于以下的概念,都會(huì)有實(shí)體例子配合著,給大家演示,希望給歷險(xiǎn)中的你帶來一些幫助!!!


(資料圖片)

一.增強(qiáng)for介紹

for-each循環(huán)是jdk1.5引入的新的語(yǔ)法功能。并不是所有東西都可以使用這個(gè)循環(huán)的??梢钥聪翴terable接口的注釋,它說明了除了數(shù)組外,其他類想要使用for-each循環(huán)必須實(shí)現(xiàn)這個(gè)接口。這一點(diǎn)表明除了數(shù)組外的for-each可能底層是由迭代器實(shí)現(xiàn)的。

Iterable接口在1.8之前只有一個(gè)方法,Iteratoriterator(),此方法返回一個(gè)迭代器。由于更早出現(xiàn)的Collection接口中早就有了這個(gè)同樣的方法,所以只需要讓Collection接口繼承Iterable接口,基于Collection的集合類就可以不做任何更改就使用for-each循環(huán)。

對(duì)于數(shù)組,因?yàn)閿?shù)組不實(shí)現(xiàn)Iterable接口,它的for-each實(shí)現(xiàn)原理應(yīng)該和Collection不一樣。

1.1缺點(diǎn):

1、對(duì)于數(shù)組,不能方便的訪問下標(biāo)值;

2、對(duì)于集合,與使用Interator相比,不能方便的刪除集合中的內(nèi)容(在內(nèi)部也是調(diào)用Interator).

除了簡(jiǎn)單遍歷并讀取其中的內(nèi)容外,不建議使用增強(qiáng)的for循環(huán)。

1.3.知識(shí)點(diǎn)詳解

1.3.1遍歷數(shù)組

語(yǔ)法為:

for (Type value : array) {       expression value;    }
代碼演示 :

以前我們這樣寫:

public class Test{       public static void main(String args[]){           int[]array = {1,2,5,8,9};           int total = 0;           for(int i = 0; i < array.length; i++){              total += array[i];           }           System.out.println(total);       }    }

現(xiàn)在我們只需這樣寫(和以上寫法是等價(jià)的):

public class Test{       public static void main(String args[]){           int[]array = {1,2,5,8,9};           inttotal = 0;           for(int n : array){                total+= n;           }           System.out.println(total);       }    }

這種循環(huán)的缺點(diǎn)是:

(1)只能順次遍歷所有元素,無法實(shí)現(xiàn)較為復(fù)雜的循環(huán),如在某些條件下需要后退到之前遍歷過的某個(gè)元素

(2)循環(huán)變量(i)不可見,如果想知道當(dāng)前遍歷到數(shù)組的第幾個(gè)元素

1.4遍歷集合

語(yǔ)法為:

for(Type value : Iterable) {       expressionvalue;    }

注意:增強(qiáng)for循環(huán)遍歷的集合必須是實(shí)現(xiàn)Iterable接口的。

代碼演示:

以前我們這樣寫:

void someFunction (){       List list = new ArrayList();       list.add("Hello");       list.add("Java");       list.add("World!");       Strings = "";       for(Iterator iter = list.iterator(); iter.hasNext();){          String temp= (String) iter.next();           s+= temp;       }       System.out.println(s);    }

現(xiàn)在我們這樣寫:

void someFunction (){       List  list = new ArrayList();       list.add("Hello");       list.add("Java");       list.add("World!");       Strings = "";       for(Object o : list){           Stringtemp = (String) o;           s+= temp;       }       System.out.println(s);    }

1.5代碼訓(xùn)練

增強(qiáng)型的??for循環(huán)??優(yōu)點(diǎn)主要體現(xiàn)在集合中

1.5.1題目

使用增強(qiáng)for循環(huán)遍歷字符串“hello World!”。

1.5.2實(shí)驗(yàn)步驟

使用String類的toCharArray()方法

代碼演示:
package com.Test;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class Main {              private final static String name = "磊哥的java歷險(xiǎn)記-@51博客";              public static  void main(String args[]){                     String s = "Hello World!";                     for(char ch:s.toCharArray()){                            System.out.println(ch);                     }                     System.out.println(name);              }               }

二.迭代器介紹

迭代器(iterator)有時(shí)又稱游標(biāo)(cursor)是程序設(shè)計(jì)的軟件設(shè)計(jì)模式,可在容器(container,例如鏈表或陣列)上遍訪的接口,設(shè)計(jì)人員無需關(guān)心容器的內(nèi)容。

迭代器(iterator)是一種對(duì)象,它能夠用來遍歷標(biāo)準(zhǔn)模板庫(kù)容器中的部分或全部元素,每個(gè)迭代器對(duì)象代表容器中的確定的地址。迭代器修改了常規(guī)指針的接口,所謂迭代器是一種概念上的抽象:那些行為上像迭代器的東西都可以叫做迭代器。然而迭代器有很多不同的能力,它可以把抽象容器和通用算法有機(jī)的統(tǒng)一起來。

2.1內(nèi)容

集合用來持有數(shù)據(jù),一定會(huì)設(shè)計(jì)出對(duì)數(shù)據(jù)的增、刪、改、查四個(gè)常用方法,而查是集合中最常用的功能。Collection接口繼承了Iterable接口,具備了可迭代功能iterator方法,該方法用于迭代集合。所以,所有單列集合由于是Collection的直接或間接實(shí)現(xiàn)類,均具有該方法。

這里涉及到以下內(nèi)容共同完成集合的迭代:

Collection接口的iterator方法,所以單列集合實(shí)現(xiàn)類均有該方法

iterator方法的返回值類型Iterator接口類型

Iterator接口的兩個(gè)方法:hasNext與next方法

2.2迭代常規(guī)步驟

(1)通過集合獲取這個(gè)集合的迭代器

(2)結(jié)合使用迭代器的hashNext與next完成集合迭代

代碼演示:

package com.Test;import java.util.ArrayList;import java.util.Iterator;public class Main {              private final static String name = "磊哥的java歷險(xiǎn)記-@51博客";              public static  void main(String args[]){                     ArrayList arrayList = new ArrayList<>();                     arrayList.add("磊哥的java歷險(xiǎn)記-@51博客");                     //返回迭代器                     Iterator iterator = arrayList.iterator();                     //調(diào)用hasNext與next完成集合迭代                     while(iterator.hasNext()) {                            String string= iterator.next();                            System.out.println(string);                     }              }               }

2.3Collection接口的Iterator

方法聲明為:

Iterator<集合中數(shù)據(jù)類型>iterator()

用來返回專屬于該集合對(duì)象的迭代器對(duì)象(Iterator的子類對(duì)象)。

2.4.Iterator接口

該接口規(guī)定了迭代集合所需要的方法

2.5.Iterator接口的兩個(gè)方法:hasNext與next方法

Iterator規(guī)定了兩個(gè)方法,集合對(duì)象產(chǎn)生的迭代器對(duì)象正是通過這兩個(gè)方法幫助集合進(jìn)行迭代工作的。

調(diào)用迭代器的hasNext方法判斷是否有下一個(gè)元素

調(diào)用迭代器的next獲取下一個(gè)元素

2.6.迭代集合元素圖解:

2.7代碼演示

package com.Test;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;/* * Iterator iterator() 返回在此 collection 的元素上進(jìn)行迭代的迭代器。 * * Iterator 就是幫你去做遍歷集合操作 . * * iterator() 返回的就是 Iterator接口的子類對(duì)象. */public class Main {       public static void main(String[] args) {              Collection c  = new ArrayList();              c.add("磊哥的java歷險(xiǎn)記-@51博客");              c.add("888");              // 遍歷集合.   獲取其中每一個(gè)元素.              // 1.獲取迭代器對(duì)象  .              Iterator iterator= c.iterator();  // Iterator 接口  指向 子類對(duì)象.              // 2.調(diào)用迭代器的方法,獲取集合中的元素.              //  Object next = iterator.next();              //  System.out.println(next);              //              //  Object next2 = iterator.next();              //  System.out.println(next2);              //              //  Object next3 = iterator.next();              //  System.out.println(next3);              //              //  Object next4 = iterator.next();              //  System.out.println(next4);              //              //  Object next5 = iterator.next(); //NoSuchElementException              //  System.out.println(next5);              while(iterator.hasNext()){                     Object next = iterator.next();                     System.out.println(next);              }       }}

2.8迭代器遍歷集合總結(jié)

package com.Test;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;/* * 1.hasNext 方法和  next方法說明 . 遍歷之前,有一個(gè)指針指向初始位置,第一個(gè)元素的前面, *  hasNext,判斷是否在指針后面有元素,有返回true ,沒有返回false. *   如果有 , 就可以通過 next() 獲取下一個(gè)元素了. * 2.syso(c); 我也能看所有的元素, 那我為什么還要遍歷呢? * * 3.toString() 在哪重寫的呢? 你管的著么!!   要找找他爹,他爺爺 * */public class Main {       public static void main(String[] args) {              Collection c = new ArrayList<>();              c.add("磊哥的java歷險(xiǎn)記-@51博客");              c.add("666");              // 遍歷集合              // 1.獲取迭代器              Iterator iterator = c.iterator();              // 2.通過迭代器獲取元素 .              while(iterator.hasNext()) { // 是否有下一個(gè).                     Object next = iterator.next(); // 獲取下一個(gè)元素                     System.out.println(next);              }       }}

2.9并發(fā)修改異常(擴(kuò)展)

迭代的常規(guī)用法中我們要盡量避免在迭代過程中為集合添加/刪除數(shù)據(jù)。否則會(huì)報(bào)錯(cuò),原因是Java拋出了并發(fā)修改異常。

迭代過程中并發(fā)修改異常的原因?yàn)榈髦小庇洃洝钡募祥L(zhǎng)度與集合中實(shí)際長(zhǎng)度不同,而導(dǎo)致出現(xiàn)索引與實(shí)際元素不符甚至無限循環(huán)的情況發(fā)生。

所以在使用Iterator時(shí),避免類似操作,for循環(huán)底層為迭代器實(shí)現(xiàn),所以也需要避免類似操作。

有些迭代器避免了這樣的問題,如ListIterator,但該類并不通用也不常用,實(shí)際開發(fā)中很少使用,只需要簡(jiǎn)單了解。

java中提供了很多個(gè)集合,它們?cè)诖鎯?chǔ)元素時(shí),采用的存儲(chǔ)方式不同。我們要取出這些集合中的元素,可通過一種通用的獲取方式來完成。

代碼演示:
package com.Test;import java.util.*;/* *  并發(fā)修改異常:當(dāng)你 遍歷集合并操作集合,添加或者移除元素的使用,可能會(huì)報(bào)出并發(fā)修改異常. *  處理方式:添加,移除 ,使用迭代器的方法. 迭代器中的remove. *  查看異常信息: 第一行是異常的說明 _空指針 ,角標(biāo)越界, 并發(fā)..... *       詳細(xì)異常信息, 從下往上看, 能看懂哪行就是你發(fā)生異常的地方,基本上就是你寫錯(cuò)代碼. *      Iterator.next()繼續(xù)迭代的時(shí)候報(bào)錯(cuò), 那么我們提供一種解決方案, 可以修改,但是不再遍歷集合. * *  解決方案: *  1.采用 Iterator中的方法去操作集合  -- 推薦 ! *  2.使用非Iterator中的方法操作, 那么再操作之后 ,加 break; * */public class Main {       public static void main(String[] args) {              Collection c = new ArrayList();              c.add("磊哥的java歷險(xiǎn)記-@51博客");              c.add("666");              c.add("I Love Java");              System.out.println(c);              Iterator iterator = c.iterator();              while(iterator.hasNext()) {                     String string=  iterator.next();                     // 如果存在666 ,那么添加一個(gè)888                     if(string.equals("666")) {                            c.add("888");                            break;                     }              }              System.out.println(c);   //java.util.ConcurrentModificationException 并發(fā)修改異常              List l = new ArrayList<>();              ListIterator listIterator= l.listIterator();       }}

結(jié)語(yǔ):

沒人會(huì)一直順利,愿你更加強(qiáng)大,然后終于有一天,可以笑著講述那些曾讓你哭的瞬間!

因?yàn)樽陨碓?,很長(zhǎng)一段時(shí)間沒有更新文章,后面我會(huì)接著之前的大綱更新的,希望能夠幫助看到我文章的兄弟們,特別是初學(xué)者!感謝大家持續(xù)關(guān)注! ! !

標(biāo)簽: 解決方案

上一篇:今日快訊:一位山東“藍(lán)胖子”是怎樣將他的數(shù)字人技術(shù)推向國(guó)內(nèi)前列的
下一篇:天天短訊!Spring AMQP項(xiàng)目