for-each(enhanced for loop )
接下来向你介绍的Tiger新特性,应该是大家比较期待的一个,在前面的例子里已经数次出现。
对了,就是 for-each(enhanced for loop )特性了。
for-each(enhanced for loop ),说得全一点应该是 for each element in the aggregation 。顾名思义,就是在for循环中逐个取出集合中的元素。
它的语法是
for(Type i : 集合){
i ...
}
这里的集合包括两种:
第一种是实现java.lang.Iterable接口的类,第二种就是array(数组)。
java.lang.Iterable是一个Tiger新引入的接口.在Tiger中,java.util.Colletcion 接口直接继承了 Iterable 接口。所以,所有Colletcion的子类都可以用于for-each语法里。同时,由于java.util.Map 接口里有 Collection<V>; values(),Set<Map.Entry<K,V>;>; entrySet() 和 Set<K>; keySet()三个方法返回Collention的子类。所以所有Map的子类也是可以间接的使用在for-each语句里的。
还是先来看一个例子吧.
[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使我们更方便对集合里的元素进行遍历。实际上,编译器在处理Iterable和array时,分别采用如下的方法进行转换
[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]
不过,值得注意的是,在Iterable中,for-each遍历是concurrent的,也就是说,在对Iterable进行遍历时,Iterable对象是不能改变的。这意味着我们不可以通过for-each进行移除以及修改的动作.
[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++;
}
}
}
//运行
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]
创建我们的可以直接用于for-each的类
通常,我们都通过数组或者是Collection/Map的子类来使用for-each语句,当然我们也可以创建自己的for-each类(Iterable)
java.lang.Iterable是一个Tiger新引入的接口,它要求实现的方法只有一个,就是 Iterator<T>; iterator().这就要求我们需要去构造一个Iterator.Iterator接口有三个方法:boolean hasNext(),Type next()和remove(),其中remove为optional opreration,可以不必实现。
下面的例子使用了一个Iterator的内部类,就其意义来说,是实现一组的平方数的一个迭代。(现实中也许永远不需这种用法 :) )
[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;//平方数
currentPos+=step;
return ret;
}
};
}
public static void main(String args[]){
MyForEach m1 = new MyForEach();
for(Object o:m1)
System.out.println(o);
}
}
[/code]
还是那句老话,自己好好体会一下吧。