Java for-each輪回應用困難2例(高等應用辦法)。本站提示廣大學習愛好者:(Java for-each輪回應用困難2例(高等應用辦法))文章只能為提供參考,不一定能成為您想要的結果。以下是Java for-each輪回應用困難2例(高等應用辦法)正文
Java中,for-each輪回簡化了任何Collection或array的遍歷進程,但其實不是每一個Java法式員都懂得本文將要描寫的for-each 輪回的一些細節。與 Java5 宣布的其他術語:釋放別號泛型,主動封裝和可變參數分歧,Java開辟者對for-each輪回的應用比任何其他特征加倍頻仍,但當問及高等的for-each輪回如何任務,或甚麼是在for-each輪回中應用Collection時的根本需求時,就不是每一個人都可以或許答復的了。
本篇教程和例子旨在經由過程深刻研討for-each 輪回中幾個風趣的困難來彌補上述空白(解釋上述成績)。好了,不再贅述,一路看看我們在Java5 for-each輪回的第一個成績。
高等輪回成績 1
斟酌上面這段遍歷一個用戶自界說的aggregator或collection類的代碼,這段代碼將會打印出甚麼,拋出異常照樣編譯器毛病:
package test;
/**
* Java Class to show how for-each loop works in Java
*/
public class ForEachTest {
public static void main(String args[]){
CustomCollection<String> myCollection = new CustomCollection<String>();
myCollection.add("Java");
myCollection.add("Scala");
myCollection.add("Groovy");
//What does this code will do, print language, throw exception or compile time error
for(String language: myCollection){
System.out.println(language);
}
}
}
上面是我們的CustomCollection類,這是個參數為泛型的類,與任何其他的Collection類類似,依附於ArrayList並供給從Collection中添加和刪除項的辦法。
package test;
public class CustomCollection<T>{
private ArrayList<T> bucket;
public CustomCollection(){
bucket = new ArrayList();
}
public int size() {
return bucket.size();
}
public boolean isEmpty() {
return bucket.isEmpty();
}
public boolean contains(T o) {
return bucket.contains(o);
}
public boolean add(T e) {
return bucket.add(e);
}
public boolean remove(T o) {
return bucket.remove(o);
}
}
謎底:
上述代碼將沒法經由過程編譯,這是由於我們的CustomCollection類沒有完成java.lang.Iterable接口,編譯期毛病以下:
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - for-each not applicable to expression type
required: array or java.lang.Iterable
found: test.CustomCollection
at test.ForEachTest.main(ForEachTest.java:24)
從中懂得到的一個風趣的現實是:for-each輪回僅運用於完成了Iterable接口的Java array和Collection類,並且既然一切內置Collection類都完成了java.util.Collection接口,曾經繼續了Iterable,這一細節平日會被疏忽,這點可以在Collection接口的類型聲明“ public interface Collection extends Iterable”中看到。所認為懂得決上述成績,你可以選擇簡略地讓CustomCollection完成Collection接口或許繼續AbstractCollection,這是默許的通用完成並展現了若何同時應用籠統類和接口以獲得更好的靈巧性。如今讓我們來看看for-each輪回的第二個困難:
Java for-each輪回的第二個困難:
鄙人面的代碼示例將會拋出ConcurrentModificationException異常。這裡我們應用尺度iterator和for-each輪回遍歷ArrayList,隨後刪除元素,你須要找出哪段代碼將會拋出ConcurrentModificationException ,為何?請留意,謎底能夠是兩個都邑,都不會或個中之一。
package test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* Java class to demonstrate inner working of for-each loop in Java
* @author Javin Paul
**/
public class ForEachTest2 {
public static void main(String args[]){
Collection<String> list = new ArrayList<String>();
list.add("Android");
list.add("iPhone");
list.add("Windows Mobile");
// Which Code will throw ConcurrentModificationException, both,
// none or one of them
// example 1
Iterator<String> itr = list.iterator();
while(itr.hasNext()){
String lang = itr.next();
list.remove(lang);
}
// example 2
for(String language: list){
list.remove(language);
}
}
}
年夜約70%的Java開辟者都邑說第一個代碼塊會拋出ConcurrentModificationException異常,由於我們沒有效iterator的remove辦法來刪除元素,而是應用ArrayList的 remove()辦法。然則,沒有若干Java開辟者會說出for-each輪回也會湧現異樣的成績,由於我們在這裡沒有應用iterator。現實上,第二個代碼片斷也會拋出ConcurrentModificationException異常,這點在處理了第一個迷惑以後就變得很顯著了。既然for-each輪回外部應用了Iterator來遍歷Collection,它也挪用了Iterator.next(),這會檢討(元素的)變更並拋出ConcurrentModificationException。你可以從上面的輸入中懂得到這點,在正文失落第一個代碼段後,當你運轉第二個代碼段時會獲得上面的輸入。
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at test.ForEachTest2.main(ForEachTest2.java:34)
以上就是關於Java5 for-each輪回的全體內容。我們曾經看到了Java法式員在編寫遍歷Collection類的代碼時發生的許多成績,特殊是在遍歷collection的同時刪除元素的時刻。請切記,在從任何Collection(例如Map、Set或List)中刪除對象時總要應用Iterator的remove辦法,也請謹記for-each輪回只是尺度Iterator代碼尺度用法之上的一種語法糖(syntactic sugar)罷了。
譯者注:語法糖(syntactic sugar),也譯為糖衣語法,是由英國盤算機迷信家彼得·約翰·蘭達-Peter J. Landin創造的一個術語,指盤算機說話中添加的某種語法,這類語法對說話的功效並沒有影響,然則更便利法式員應用。平日來講應用語法糖可以或許增長法式的可讀性,從而削減法式代碼失足的機遇。