for-each(enhanced for loop )
接下來(lái)向你介紹的Tiger新特性,應(yīng)該是大家比較期待的一個(gè),在前面的例子里已經(jīng)數(shù)次出現(xiàn)。
對(duì)了,就是 for-each(enhanced for loop )特性了。
for-each(enhanced for loop ),說(shuō)得全一點(diǎn)應(yīng)該是 for each element in the aggregation 。顧名思義,就是在for循環(huán)中逐個(gè)取出集合中的元素。
它的語(yǔ)法是
for(Type i : 集合){
i ...
}
這里的集合包括兩種:
第一種是實(shí)現(xiàn)java.lang.Iterable接口的類,第二種就是array(數(shù)組)。
java.lang.Iterable是一個(gè)Tiger新引入的接口.在Tiger中,java.util.Colletcion 接口直接繼承了 Iterable 接口。所以,所有Colletcion的子類都可以用于for-each語(yǔ)法里。同時(shí),由于java.util.Map 接口里有 Collection<V>; values(),Set<Map.Entry<K,V>;>; entrySet() 和 Set<K>; keySet()三個(gè)方法返回Collention的子類。所以所有Map的子類也是可以間接的使用在for-each語(yǔ)句里的。
還是先來(lái)看一個(gè)例子吧.
[code]
//TestForEach.java
import java.util.*;
public class TestForEach{
public static void main(String arg[]){
ArrayList list = new??ArrayList();
list.add("asdf");
list.add("fdaf");
list.add("dfafds");
list.add("dsafdsaf");
int i=1;
for(Object s : list){
list.remove(s);
System.out.println("element "+i+"??is:"+s);
i++;
}
i=1;
Object o[] = list.toArray();
for(Object s : o){
System.out.println("element "+i+"??is:"+s);
i++;
}
}
}
[/code]
for-each使我們更方便對(duì)集合里的元素進(jìn)行遍歷。實(shí)際上,編譯器在處理Iterable和array時(shí),分別采用如下的方法進(jìn)行轉(zhuǎn)換
[code]
Iterable:
??for ( Iterator<E>; #i = Expression.iterator(); #i.hasNext(); ) {
??FormalParameter = #i.next();
??Statement
? ? }
array:
Type[] #a = Expression;
L1: L2: ... Lm://The possibly empty sequence of labels preceding the enhanced for loop is represented by L1: L2: ... Lm. This sequence is moved beyond the assignment to #a so that continue and break statements with labels will work properly.
? ? for (int #i = 0; #i < #a.length; #i++) {
? ?? ???FormalParameter = #a[ #i ] ;
? ? ? ? Statement
? ? }
[/code]
不過(guò),值得注意的是,在Iterable中,for-each遍歷是concurrent的,也就是說(shuō),在對(duì)Iterable進(jìn)行遍歷時(shí),Iterable對(duì)象是不能改變的。這意味著我們不可以通過(guò)for-each進(jìn)行移除以及修改的動(dòng)作.
[code]
//TestForEach2.java
import java.util.*;
public class TestForEach2{
public static void main(String arg[]){
ArrayList list = new??ArrayList();
list.add("asdf");
list.add("fdaf");
list.add("dfafds");
list.add("dsafdsaf");
int i=1;
for(Object s : list){
System.out.println("removing element "+i+" :"+s);
list.remove(s);//java.util.ConcurrentModificationException
i++;
}
}
}
//運(yùn)行
removing element 1 :asdf
java.util.ConcurrentModificationException
? ? ? ? at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:449)
? ? ? ? at java.util.AbstractList$Itr.next(AbstractList.java:420)
? ? ? ? at TestForEach.main(TestForEach.java:11)
Exception in thread "main" Normal Termination
[/code]
創(chuàng)建我們的可以直接用于for-each的類
通常,我們都通過(guò)數(shù)組或者是Collection/Map的子類來(lái)使用for-each語(yǔ)句,當(dāng)然我們也可以創(chuàng)建自己的for-each類(Iterable)
java.lang.Iterable是一個(gè)Tiger新引入的接口,它要求實(shí)現(xiàn)的方法只有一個(gè),就是 Iterator<T>; iterator().這就要求我們需要去構(gòu)造一個(gè)Iterator.Iterator接口有三個(gè)方法:boolean hasNext(),Type next()和remove(),其中remove為optional opreration,可以不必實(shí)現(xiàn)。
下面的例子使用了一個(gè)Iterator的內(nèi)部類,就其意義來(lái)說(shuō),是實(shí)現(xiàn)一組的平方數(shù)的一個(gè)迭代。(現(xiàn)實(shí)中也許永遠(yuǎn)不需這種用法 :) )
[code]
//MyForEach.java
import java.util.*;
public class MyForEach implements Iterable{
int start,end;
int step=1;
public MyForEach(){
start=5;
end=10;
}
public MyForEach(int start){
this.start=start;
end=start+5;
}
public MyForEach(int start,int end){
this.start=start;
this.end=end;
if(start<end)
? ? ? ? step=-1;
}
public Iterator iterator(){
return new Iterator(){//inner class of Iterator
? ? ? ? int currentPos=start;
? ? ? ? public void remove(){
? ? ? ? ? ? ? ? //do nothing
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???throw new UnsupportedOperationException();
? ? ? ? }
? ? ? ? public boolean hasNext(){//check if exceed the end??
? ? ? ? ? ? ? ? return (step>;0)^(currentPos>;end);
? ? ? ? }
? ? ? ? public Object next(){
? ? ? ? ? ? ? ? if(!hasNext())
? ? ? ? ? ? ? ? ? ? ? ? throw new NoSuchElementException();
? ? ? ? ? ? ? ? int ret=currentPos*currentPos;//平方數(shù)
? ? ? ? ? ? ? ? currentPos+=step;
? ? ? ? ? ? ? ? return ret;
? ? ? ? ? ? ? ? }
? ? ? ? };
}
public static void main(String args[]){
MyForEach m1 = new MyForEach();
for(Object o:m1)
? ? ? ? System.out.println(o);
}
}
[/code]
還是那句老話,自己好好體會(huì)一下吧。