声明:
主要代码参考自算法(第四版),这里将代码列出,是想和大家交流一些学习心得。
1.前言
先说个小疑问
我们知道集合想要实现迭代,就必须实现Iterable接口,然后重写iterator()方法,从而返回Iterator对象,最后再利用Iterator对象的hasNext()方法和next()方法实现迭代,那么为什么不直接实现Iterator接口呢?
原因是:
因为Iterator接口的核心方法next()或者hasNext() 是依赖于迭代器的当前迭代位置的。 如果Collection直接实现Iterator接口,势必导致集合对象中包含当前迭代位置的数据(指针)。 当集合在不同方法间被传递时,由于当前迭代位置不可预置,那么next()方法的结果会变成不可预知。 除非再为Iterator接口添加一个reset()方法,用来重置当前迭代位置。但即时这样,Collection也只能同时存在一个当前迭代位置,而Iterable则不然,每次调用都会返回一个从头开始计数的迭代器,多个迭代器是互不干扰的。(引用自:http://blog.csdn.net/aa8568849/article/details/52650452)
好,那么就构建一下实现下压栈的思路。
2.思路
2.1
定义成员属性和基本方法
成员属性:
包括数组的创建和数组中元素的数量
2.2
创建下压栈类并实现Iterable接口,并且实现iterator()方法,用于返回Iterator对象。
2.3
创建内部类并实现Iterator接口,并实现hasNext()和next()方法,这样就可以实现迭代。
2.4
定义调整数组大小的方法
2.5
定义压栈和弹栈的方法
3.代码
3.1
定义成员属性和基本方法:
这里设定了数组的初始大小为1.
注:
Java中不允许创建泛型数组,所以这里创建Object类型的,然后再强转。
3.2
创建下压栈类并实现Iterable接口:
实现iterator()方法:
3.3
创建内部类并实现Iterator接口,并实现hasNext()和next()方法:
注:
next()先输出栈顶元素。
3.4
定义调整数组大小的方法。
3.5
定义压栈和弹栈的方法:
4.完整代码
import java.util.ArrayList;
import java.util.Iterator;
//用数组实现的栈(可以调整栈的大小) p88
//集合想要迭代的话需满足两个条件 1.返回Iterator对象 2.Iterator类包含hasNext()和next()
public class ResizingArrayStack<Item> implements Iterable<Item> {
Item[] a = (Item[]) new Object[1]; //数组装载栈元素
private int N = 0; //集合中的元素数量
//返回数组是否为空
public boolean isEmpty(){ return N == 0; }
//返回栈中元素的数量
public int size(){ return N; }
//调整数组的大小
public void resize(int newSize){
//将栈中的元素移动到新的大小为newSize的数组中
Item[] temp = (Item[]) new Object[newSize];
for(int i=0; i<N; i++) temp[i] = a[i];
a = temp; //引用指向新数组
}
//压栈操作,将元素添加到栈顶
public void push(Item item){
//数组若满,则创建新数组(大小为原来2倍)
if(N == a.length) resize(2*a.length);
a[N++] = item;
}
//弹栈操作,将元素从栈顶移除
public Item pop(){
//获得栈顶元素
Item item = a[--N]; //同时使N值减1
a[N] = null; //避免对象游离
if(N>0 && N == a.length/4) resize(a.length/2); //元素为1/4,则变1/2
return item; //返回弹出的元素
}
//重写iterator()从而返回Iterator对象
@Override
public Iterator<Item> iterator() {
return new ReverseArrayIterator();
}
//定义嵌套类ReverseArrayIterator(方便访问a[]和N)
public class ReverseArrayIterator implements Iterator<Item>{
//支持后进先出的迭代
private int i = N;
@Override
public boolean hasNext() { return i > 0; }
@Override
public Item next() { return a[--i]; }
public void remove() {}
}
}
5.测试
完整代码:
import java.util.Iterator;
import basis.ResizingArrayStack;
public class MyTest {
public static void main(String[] args) {
new MyTest().start();
}
private void start() {
ResizingArrayStack<String> ras = new ResizingArrayStack<String>();
System.out.println("栈是否为空:"+ras.isEmpty());
System.out.println("栈的大小"+ras.size());
ras.push("元素0");
ras.push("元素1");
ras.push("元素2");
ras.push("元素3");
ras.push("元素4");
ras.push("元素5");
ras.push("元素6");
ras.push("元素7");
System.out.println("栈是否为空:"+ras.isEmpty());
System.out.println("栈的大小"+ras.size());
String str = ras.pop();
System.out.println("弹出的元素是:"+str);
Iterator<String> iterator = ras.iterator();
while( iterator.hasNext() )
System.out.println(iterator.next());
}
}
输出: