栈结构在计算机的世界中太常见了,可以说无法离开,比如方法栈、回退功能、邮件接收按照栈结构排列等等。
我们接下来利用数组来实现一个简单的动态扩容栈,上代码,代码中注释描述了我们的设计思路。
//我们先设计出API
/**设计思路:
* 首先它是一个栈结构,那么必然有出栈入栈的方法,
* 出栈可以返回栈内的数据,入栈方法的返回类型需要确认是否入栈成功boolean
* 另外栈空间有多少元素,需要一个变量来保存,通过公共方法返回,
* 为保证栈持续可用,引入动态扩容,所谓的动态扩容,就是在出入栈方法中判断栈空间容量,
* 在容量逼近当前极限时,扩容数组,元素减少很多时,将数组容量减小,节省内存空间,
* 另外再实现Iterable接口中的Iterator方法,给一个遍历栈结构的方法
import java.util.Iterator;
public class ResizingArrayStack<Item> implements Iterable<Item> {
/**
* 给一个初使容量,这个10是参考了ArrayList
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 使用数组作为栈结构容器
*/
private Item[] elementData = (Item[]) new Object[DEFAULT_CAPACITY];
/**
* 元素实际数量
*/
private int size;
/**
* 入栈
* @param item 元素
* @return true/false
*/
public boolean push(Item item){
if (size == elementData.length){
resize(2* elementData.length);
}
elementData[size++] = item;
return true;
}
/**
* 出栈
* @return
*/
public Item pop(){
//取出栈顶元素,避免对象游离
Item item = elementData[--size];
elementData[size] = null;
if (size > 0&& size <= elementData.length/4){
resize(elementData.length/2);
}
return item;
}
public int size(){
return size;
}
/**
* 数组容量变化
* @param max
*/
private void resize(int max){
Item[]newElementData = (Item[]) new Object[max];
for (int i=0; i < size;i++){
newElementData[i] = elementData[i];
}
elementData = newElementData;
}
@NotNull
@Override
public Iterator<Item> iterator() {
return new ResizingArrayStackIterator();
}
private class ResizingArrayStackIterator implements Iterator<Item>{
private int i = size;
@Override
public boolean hasNext() {
return i > 0;
}
@Override
public Item next() {
return elementData[--i];
}
}
public static void main(String[]args){
ResizingArrayStack<String>arrayStack = new ResizingArrayStack<>();
for (int i = 0; i< 1000;i++){
arrayStack.push(i+"==="+i);
}
System.out.println(arrayStack.size());
for(String s : arrayStack){
System.out.println(s);
}
// Iterator<String> iterator = arrayStack.iterator();
// while (iterator.hasNext()){
// System.out.println(iterator.next());
// }
}
}
之后我们会再用链表结构来设计一个栈结构。