1.3.12
编写一个可迭代的Stack用例,它含有一个静态的copy()方法,接受一个字符串的栈作为参数并返回该栈的一个副本。注意:这种能力是迭代器价值的一个重要体现,因为有了它我们无需改变基本API就能够实现这种功能。
强势分析一波,我们可以在Stack的API里实现一个copy方法,只需要两个栈,第一次遍历将给我们的字符串入栈,然后将得到的新的栈再次入栈,就实现了copy,返回结果即可。上代码:
/**
* 用链表实现下压栈
*
* @author wangxinfu
*/
public class Stack<Item> implements Iterable<Item> {
private int size;
private Node first;
private class Node {
Item item;
Node next;
}
private class StackIterator implements Iterator<Item> {
//当前结点
Node current = first;
@Override
public boolean hasNext() {
return current != null;
}
@Override
public Item next() {
if (!hasNext()) {
throw new NoSuchElementException("Stack is Empty!");
}
Item item = current.item;
current = current.next;
return item;
}
}
/**
* 压栈 此处无需判断isEmpty()
* @param item
* @return
*/
public boolean push(Item item) {
//在头结点添加
Node oldFirst = first;
first = new Node();
first.item = item;
first.next = oldFirst;
size++;
return true;
}
public Item pop() {
if (isEmpty()) {
throw new NoSuchElementException("Stack is Empty");
}
//暂存item
Item item = first.item;
Node next = first.next;
first.item = null;
first.next = null;
first = next;
size--;
return item;
}
public boolean destroy(){
while (first !=null){
pop();
}
return true;
}
@Override
public Iterator<Item> iterator() {
return new StackIterator();
}
public int size() {
return size;
}
public boolean isEmpty() {
return first == null;
}
public Item top(){
if (isEmpty()){throw new NoSuchElementException("Stack underflow");}
return first.item;
}
/**
* 返回一个副本
* @param stackString
* @return
*/
public static <T> Stack<T> copy(Stack<T> stackString){
Stack<T>stack = new Stack<>();
Stack<T> resStack = new Stack<>();
for (T str:stackString){
stack.push(str);
}
while (stack.iterator().hasNext()){
resStack.push(stack.pop());
}
//help gc
stack.destroy();
return resStack;
}
public static Stack<String> copyString(Stack<String>stringStack){
return Stack.copy(stringStack);
}
// test
public static void main(String[]args){
Stack<String>stack = new Stack<>();
for (int i = 0;i<100;i++){
stack.push(""+i);
}
Stack<String> copyString = copyString(stack);
for (String str:copyString){
System.out.println(str);
}
copyString.destroy();
System.out.println(copyString.size());
}
}