Java中的Iterable和Iterator

由于是Java初学者,对于这个概念不是特别明白。今天看了一篇博文对这个问题有了进一步的理解。

博文地址:http://blog.dreasgrech.com/2010/03/javas-iterators-and-iterables.html

前几天在写coursera的AlgorithmsI这门课程的作业的时候不太明白为什么有时候用Iterator有时候用Iterable,下面谈一下自己的体会。

在写RandomizeQueue这个类的时候,要返回一个iterator,因为这不是java内建的容器类,没有实现过iterator这个方法,因此我们需要实现iterator这个接口,来实现我们自己的iterator方法,因此需要重载hasNext,next,remove等方法,这样我们才能获得RandomizedQueue这个类的iterator。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public Iterator<Item> iterator() {        // return an independent iterator over items in random order  
  2.         return new RandomizedQueueIterator();  
  3.     }  
  4.       
  5.     private class RandomizedQueueIterator implements Iterator<Item> {  
  6.           
  7.         private Item[] randomItems;  
  8.         private int index;  
  9.         public RandomizedQueueIterator() {  
  10.             this.index = 0;  
  11.             randomItems = (Item[]) new Object[itemCount];  
  12.             for (int i = 0; i < itemCount; ++i) {  
  13.                 randomItems[i] = items[i];  
  14.             }  
  15.             /*Knuth shuffling algorithm produces a uniformly random permutation  
  16.              * of the input array in linear time.  
  17.              * In iteration i, pick integer r between 0 and i uniformly at random  
  18.              * and then swap a[i] and a[r]*/  
  19.             Item tmpItem;  
  20.             for (int i = 0; i < itemCount; ++i) {    
  21.                 int rand = StdRandom.uniform(i+1);  
  22.                 tmpItem = randomItems[i];  
  23.                 randomItems[i] = randomItems[rand];  
  24.                 randomItems[rand] = tmpItem;  
  25.             }  
  26.             //can also use StdRandom.shuffle(randomItems);  
  27.         }  
  28.   
  29.         @Override  
  30.         public boolean hasNext() {  
  31.             // TODO Auto-generated method stub  
  32.             return index != itemCount;  
  33.         }  
  34.   
  35.         @Override  
  36.         public Item next() {  
  37.             // TODO Auto-generated method stub  
  38.             if (index == itemCount) {  
  39.                 throw new java.util.NoSuchElementException();  
  40.             }  
  41.             return randomItems[index++];  
  42.         }  
  43.   
  44.         @Override  
  45.         public void remove() {  
  46.             // TODO Auto-generated method stub  
  47.             throw new java.lang.UnsupportedOperationException();  
  48.         }  
  49.           
  50.     }  

而在下面的程序中,我们只是用了Iterable<board>的原因是因为,我们这里存储board是用了java内建的容器类(queue也好,stack也好),而这些容器类内已经实现过iterator,我们没有必要自己重新写。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /*swap blank with all its neighbors*/  
  2.     public Iterable<Board> neighbors() {  
  3.         // all neighboring boards  
  4.         Queue<Board> neighborQueue= new Queue<Board>();  
  5.         //find the blank's position  
  6.         int blankI = 0, blankJ = 0;  
  7.         boolean flag = false;  
  8.         for (int i = 0; i < this.N; ++i) {  
  9.             for (int j = 0; j < this.N; ++j) {  
  10.                 if (blocks[i][j] == 0) {  
  11.                     blankI = i;  
  12.                     blankJ = j;  
  13.                     flag = true;  
  14.                     break;  
  15.                 }  
  16.             }  
  17.             if (flag)  
  18.                 break;  
  19.         }  
  20.         //vector used to move to the 4 directions  
  21.         int[] dirI = {10, -10};  
  22.         int[] dirJ = {010, -1};  
  23.         //get position of the neighbor  
  24.         int neighborI, neighborJ;   
  25.         for (int k = 0; k < 4; ++k) {  
  26.             neighborI = blankI + dirI[k];  
  27.             neighborJ = blankJ + dirJ[k];  
  28.             if (isValidIndex(neighborI, neighborJ)) {  
  29.                 Board neighborBoard = new Board(this.blocks);  
  30.                 swap(neighborBoard, blankI, blankJ, neighborI, neighborJ);  
  31.                 neighborQueue.enqueue(neighborBoard);  
  32.             }  
  33.         }  
  34.         return  neighborQueue;  
  35.     }  
在上面的程序中,之所以我们不直接返回queue<board>的原因是:这样client程序无需关心具体的实现到底是queue还是stack,而只需要获得Iterable<Board>这个类型的对象,然后直接使用foreach语句迭代获得结果。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /*add feasible moves in the minimum priority queue*/  
  2.     private void addNeighbor(MinPQ<SearchNode> minPQ, SearchNode sn) {  
  3. //      Queue<Board> boardQueue = (Queue<Board>) sn.board.neighbors();  
  4.         Iterable<Board> iter = sn.board.neighbors();  
  5. //      for (Board b: boardQueue) {  
  6.         for (Board b: iter) {  
  7.             //use a critical optimization  
  8.             if (sn.prevSearchNode == null || !b.equals(sn.prevSearchNode.board)) {  
  9.                 minPQ.insert(new SearchNode(b, sn.move + 1, sn));  
  10.             }  
  11.         }  
  12.     }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值