Iterator与Iterable之foreach循环输出自定义类

无意中在网上看到一篇文章,把作者的想法进行了实现并进行了改进。

原文地址http://my.oschina.net/u/1412027/blog/226376

原文内容:

    

从Java5起,在Java中有了for-each循环,可以用来循环遍历collection和array。For each循环允许你在无需保持传统for循环中的索引,或在使用iterator /ListIterator时无需调用while循环中的hasNext()方法就能遍历collection。Java中,for-each循环简化了任何Collection或array的遍历过程,但并不是每个Java程序员都了解本文将要描述的for-each 循环的一些细节。与 Java5 发布的其他术语:释放别名泛型,自动封装和可变参数不同,Java开发者对for-each循环的使用比任何其他特性更加频...

考虑下面这段遍历一个用户自定义的aggregator或collection类的代码,这段代码将会打印出什么,抛出异常还是编译器错误:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package  javaForEach;
 
/**
   * 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);
         }
     }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package  javaForEach;
 
import  java.util.ArrayList;
 
 
public  class  CustomCollection<T>{
     private  ArrayList<T> bucket;
  
     public  CustomCollection(){
         bucket =  new  ArrayList<T>();
     }
  
     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接口,编译期错误如下:

Description    Resource    Path    Location    Type
Can only iterate over an array or an instance of java.lang.Iterable    ForEachTest.java    /DataSortAndJAVABasic/src/javaForEach    line 15    Java Problem
从中了解到的一个有趣的事实是:for-each循环仅应用于实现了Iterable接口的Java array和Collection类,而且既然所有内置Collection类都实现了java.util.Collection接口,已经继承了 Iterable,这一细节通常会被忽略,这点可以在Collection接口的类型声明“ public interface Collection extends Iterable”中看到。所以为了解决上述问题,你可以选择简单地让CustomCollection实现Collection接口或者继承 AbstractCollection,这是默认的通用实现并展示了如何同时使用抽象类和接口以获取更好的灵活性。


对作者的想法的实现,并且增加了反向遍历

package thinkInJavaChapter14;
import java.util.ArrayList;
import java.util.Iterator;
/**
 * 
 * @author Administrator
 *
 */
public class ForEachTest
{
/**
* 用来测试自定义类使用foreach循环
* @author Administrator
*
* @param <T>
*/
class CustomCollection<T> implements Iterable<T>{
/**
 * 
 */
   private ArrayList<T> bucket;
 
   public CustomCollection(){
       bucket = new ArrayList<T>();
   }  
   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);
   }
@Override
public Iterator<T> iterator()
{
return new Iterator<T>()
{
private int nn = 0;
public boolean hasNext(){
return nn!=bucket.size();
}
public T next(){
return bucket.get(nn++);
//return bucket;
}
@Override
public void remove()
{
throw new UnsupportedOperationException();
}
};
}
//反向输出
public Iterable<T> revese(){
/**
 * 
 */
 return new Iterable<T>()
{
 public Iterator<T> iterator(){
 return new Iterator<T>()
{
                    int index = bucket.size()-1;
@Override
public boolean hasNext()
{
// TODO Auto-generated method stub
return index>-1;
}
@Override
public T next()
{
return bucket.get(index--);
}


@Override
public void remove()
{
throw new UnsupportedOperationException();

}
 
};
 }
};
 }
}  
public static void main(String args[]){
ForEachTest f = new ForEachTest();
       CustomCollection<String> myCollection = f.new CustomCollection<String>();
       myCollection.add("1");
       myCollection.add("2");
       myCollection.add("3");  
       //What does this code will do, print language, throw exception or compile time error
       for(String language: myCollection){
           System.out.println(language.toString());
       }
       System.out.println("**********************");
       for(String language: myCollection.revese()){
           System.out.println(language.toString());
       }
   }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值