Q:什么是Iterable接口?
A:只有一个方法,放回Iterator,如下:
public interface Iterable<Item>
{
Iterator<Item> iterator();
}
A:有两个方法:hasNext()和next()。第三个方法: remove()可选
Q:为什么要用数据结构Iterable?
A:Java支持优雅的客户代码,应用场景如下:
for (String s : stack)
System.out.println(s);
Iterator<String> i = stack.iterator();
while (i.hasNext())
{
String s = i.next();
System.out.println(s);
}
下面,以Stack类实现Iterable为例,介绍Iterable的实现方法:
/*************************************************************************
* Compilation: javac Stack.java
* Execution: java Stack < input.txt
*
* A generic stack, implemented using a singly-linked list.
* Each stack element is of type Item.
*
* This version uses a static nested class Node (to save 8 bytes per
* Node), whereas the version in the textbook uses a non-static nested
* class (for simplicity).
*
* % more tobe.txt
* to be or not to - be - - that - - - is
*
* % java Stack < tobe.txt
* to be not that or be (2 left on stack)
*
*************************************************************************/
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* The <tt>Stack</tt> class represents a last-in-first-out (LIFO) stack of generic items.
* It supports the usual <em>push</em> and <em>pop</em> operations, along with methods
* for peeking at the top item, testing if the stack is empty, and iterating through
* the items in LIFO order.
* <p>
* This implementation uses a singly-linked list with a static nested class for
* linked-list nodes. See {@link LinkedStack} for the version from the
* textbook that uses a non-static nested class.
* The <em>push</em>, <em>pop</em>, <em>peek</em>, <em>size</em>, and <em>is-empty</em>
* operations all take constant time in the worst case.
* <p>
* For additional documentation, see <a href="/algs4/13stacks">Section 1.3</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Stack<Item> implements Iterable<Item> {<span style="color:#ff0000;">//声明,实现Iterable接口</span>
private int N; // size of the stack
private Node<Item> first; // top of stack
// helper linked list class
private static class Node<Item> {
private Item item;
private Node<Item> next;
}
/**
* Initializes an empty stack.
*/
public Stack() {
first = null;
N = 0;
}
/**
* Is this stack empty?
* @return true if this stack is empty; false otherwise
*/
public boolean isEmpty() {
return first == null;
}
/**
* Returns the number of items in the stack.
* @return the number of items in the stack
*/
public int size() {
return N;
}
/**
* Adds the item to this stack.
* @param item the item to add
*/
public void push(Item item) {
Node<Item> oldfirst = first;
first = new Node<Item>();
first.item = item;
first.next = oldfirst;
N++;
}
/**
* Removes and returns the item most recently added to this stack.
* @return the item most recently added
* @throws java.util.NoSuchElementException if this stack is empty
*/
public Item pop() {
if (isEmpty()) throw new NoSuchElementException("Stack underflow");
Item item = first.item; // save item to return
first = first.next; // delete first node
N--;
return item; // return the saved item
}
/**
* Returns (but does not remove) the item most recently added to this stack.
* @return the item most recently added to this stack
* @throws java.util.NoSuchElementException if this stack is empty
*/
public Item peek() {
if (isEmpty()) throw new NoSuchElementException("Stack underflow");
return first.item;
}
/**
* Returns a string representation of this stack.
* @return the sequence of items in the stack in LIFO order, separated by spaces
*/
public String toString() {
StringBuilder s = new StringBuilder();
for (Item item : this)
s.append(item + " ");
return s.toString();
}
/**
* Returns an iterator to this stack that iterates through the items in LIFO order.
* @return an iterator to this stack that iterates through the items in LIFO order.
*/
public Iterator<Item> iterator() {<span style="color:#ff0000;">//实现iterator方法,返回Iterator</span>
return new ListIterator<Item>(first);
}
// an iterator, doesn't implement remove() since it's optional
private class ListIterator<Item> implements Iterator<Item> {<span style="color:#ff0000;">//实现Iterator</span>
private Node<Item> current;
public ListIterator(Node<Item> first) {
current = first;
}
public boolean hasNext() { return current != null; }<span style="color:#ff0000;">//实现hasNext方法</span>
public void remove() { throw new UnsupportedOperationException(); }//remove方法可选
public Item next() {<span style="color:#ff0000;">//实现next方法</span>
if (!hasNext()) throw new NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
/**
* Unit tests the <tt>Stack</tt> data type.
*/
public static void main(String[] args) {
Stack<String> s = new Stack<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) s.push(item);
else if (!s.isEmpty()) StdOut.print(s.pop() + " ");
}
StdOut.println("(" + s.size() + " left on stack)");
}
}