
未來這個(gè)詞聽上去就是美好,可是你別忘了呀,每一個(gè)我們所期待的美好未來,都必須有一個(gè)努力的現(xiàn)在?。。?
我們上一篇聊到了java之集合,這一篇我們聊一下增強(qiáng)for和迭代器,針對(duì)于以下的概念,都會(huì)有實(shí)體例子配合著,給大家演示,希望給歷險(xiǎn)中的你帶來一些幫助!!!
(資料圖片)
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è)方法,Iterator
對(duì)于數(shù)組,因?yàn)閿?shù)組不實(shí)現(xiàn)Iterable接口,它的for-each實(shí)現(xiàn)原理應(yīng)該和Collection不一樣。
1、對(duì)于數(shù)組,不能方便的訪問下標(biāo)值;
2、對(duì)于集合,與使用Interator相比,不能方便的刪除集合中的內(nèi)容(在內(nèi)部也是調(diào)用Interator).
除了簡(jiǎn)單遍歷并讀取其中的內(nèi)容外,不建議使用增強(qiáng)的for循環(huán)。
語(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è)元素
語(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); }
增強(qiáng)型的??for循環(huán)??優(yōu)點(diǎn)主要體現(xiàn)在集合中
使用增強(qiáng)for循環(huán)遍歷字符串“hello World!”。
使用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)一起來。
集合用來持有數(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方法
(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[]){ ArrayListarrayList = 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); } } }
方法聲明為:
Iterator<集合中數(shù)據(jù)類型>iterator()
用來返回專屬于該集合對(duì)象的迭代器對(duì)象(Iterator的子類對(duì)象)。
該接口規(guī)定了迭代集合所需要的方法
Iterator規(guī)定了兩個(gè)方法,集合對(duì)象產(chǎn)生的迭代器對(duì)象正是通過這兩個(gè)方法幫助集合進(jìn)行迭代工作的。
調(diào)用迭代器的hasNext方法判斷是否有下一個(gè)元素
調(diào)用迭代器的next獲取下一個(gè)元素
package com.Test;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;/* * Iteratoriterator() 返回在此 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); } }}
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); } }}
迭代的常規(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) { Collectionc = 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(); }}
沒人會(huì)一直順利,愿你更加強(qiáng)大,然后終于有一天,可以笑著講述那些曾讓你哭的瞬間!
因?yàn)樽陨碓?,很長(zhǎng)一段時(shí)間沒有更新文章,后面我會(huì)接著之前的大綱更新的,希望能夠幫助看到我文章的兄弟們,特別是初學(xué)者!感謝大家持續(xù)關(guān)注! ! !
標(biāo)簽: 解決方案