由于是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。
- public Iterator<Item> iterator() { // return an independent iterator over items in random order
- return new RandomizedQueueIterator();
- }
- private class RandomizedQueueIterator implements Iterator<Item> {
- private Item[] randomItems;
- private int index;
- public RandomizedQueueIterator() {
- this.index = 0;
- randomItems = (Item[]) new Object[itemCount];
- for (int i = 0; i < itemCount; ++i) {
- randomItems[i] = items[i];
- }
- /*Knuth shuffling algorithm produces a uniformly random permutation
- * of the input array in linear time.
- * In iteration i, pick integer r between 0 and i uniformly at random
- * and then swap a[i] and a[r]*/
- Item tmpItem;
- for (int i = 0; i < itemCount; ++i) {
- int rand = StdRandom.uniform(i+1);
- tmpItem = randomItems[i];
- randomItems[i] = randomItems[rand];
- randomItems[rand] = tmpItem;
- }
- //can also use StdRandom.shuffle(randomItems);
- }
- @Override
- public boolean hasNext() {
- // TODO Auto-generated method stub
- return index != itemCount;
- }
- @Override
- public Item next() {
- // TODO Auto-generated method stub
- if (index == itemCount) {
- throw new java.util.NoSuchElementException();
- }
- return randomItems[index++];
- }
- @Override
- public void remove() {
- // TODO Auto-generated method stub
- throw new java.lang.UnsupportedOperationException();
- }
- }
而在下面的程序中,我们只是用了Iterable<board>的原因是因为,我们这里存储board是用了java内建的容器类(queue也好,stack也好),而这些容器类内已经实现过iterator,我们没有必要自己重新写。
- /*swap blank with all its neighbors*/
- public Iterable<Board> neighbors() {
- // all neighboring boards
- Queue<Board> neighborQueue= new Queue<Board>();
- //find the blank's position
- int blankI = 0, blankJ = 0;
- boolean flag = false;
- for (int i = 0; i < this.N; ++i) {
- for (int j = 0; j < this.N; ++j) {
- if (blocks[i][j] == 0) {
- blankI = i;
- blankJ = j;
- flag = true;
- break;
- }
- }
- if (flag)
- break;
- }
- //vector used to move to the 4 directions
- int[] dirI = {1, 0, -1, 0};
- int[] dirJ = {0, 1, 0, -1};
- //get position of the neighbor
- int neighborI, neighborJ;
- for (int k = 0; k < 4; ++k) {
- neighborI = blankI + dirI[k];
- neighborJ = blankJ + dirJ[k];
- if (isValidIndex(neighborI, neighborJ)) {
- Board neighborBoard = new Board(this.blocks);
- swap(neighborBoard, blankI, blankJ, neighborI, neighborJ);
- neighborQueue.enqueue(neighborBoard);
- }
- }
- return neighborQueue;
- }
- /*add feasible moves in the minimum priority queue*/
- private void addNeighbor(MinPQ<SearchNode> minPQ, SearchNode sn) {
- // Queue<Board> boardQueue = (Queue<Board>) sn.board.neighbors();
- Iterable<Board> iter = sn.board.neighbors();
- // for (Board b: boardQueue) {
- for (Board b: iter) {
- //use a critical optimization
- if (sn.prevSearchNode == null || !b.equals(sn.prevSearchNode.board)) {
- minPQ.insert(new SearchNode(b, sn.move + 1, sn));
- }
- }
- }