风人园

弱水三千,只取一瓢,便能解渴;佛法无边,奉行一法,便能得益。
随笔 - 99, 文章 - 181, 评论 - 56, 引用 - 0
数据加载中……

jdk1.5 for-each(enhanced for loop )

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]

还是那句老话,自己好好体会一下吧。

posted on 2006-12-16 16:02 风人园 阅读(1318) 评论(0)  编辑  收藏 所属分类: Java