一、基础接口设计
接口是考虑到扩展性以及规范化而准备的,我们设计的栈主要有以下这些接口,完成基本功能即可。
public interface stack {
int size();
boolean isEmpty();
void clear();
Optional<Object> pop();
Optional<Object> peek();
boolean push(Object data);
}
二、V1版本
2.1 功能简介
- 栈的基本功能满足
- 可扩容
- 使用Optional返回数据
2.2 代码
注意:我们使用top作为栈的栈顶指针,默认值为0,也就是空栈时指向0。存入数据后指向下一个位置,取数据时需要top-1来处理,也就是说我们的top始终高真实数据一个位置。
public class StackV1 implements stack {
private int top;
private int capacity = DEFAULT_SIZE;
private double expand = DEFAULT_EXPAND;
private static final int DEFAULT_SIZE = 16;
private static final double DEFAULT_EXPAND = 1.5;
Object[] data = new Object[DEFAULT_SIZE];
public StackV1() {
}
public StackV1(int capacity) {
if (capacity > 16) {
this.data = new Object[capacity];
}
}
public StackV1(int capacity, double expand) {
this.capacity = capacity;
this.expand = expand;
if (capacity > 16) {
this.data = new Object[capacity];
}
}
private void expand() {
this.capacity *= this.expand;
// 复制数组
this.data = Arrays.copyOf(this.data, this.capacity);
}
@Override
public int size() {
return this.top;
}
@Override
public boolean isEmpty() {
return this.top == 0;
}
@Override
public void clear() {
this.top = 0;
}
@Override
public Optional<Object> pop() {
if (this.top <= 0) {
return Optional.empty();
}
return Optional.of(this.data[--this.top]);
}
@Override
public Optional<Object> peek() {
if (this.top <= 0) {
return Optional.empty();
}
return Optional.of(this.data[this.top - 1]);
}
@Override
public boolean push(Object data) {
if (this.top >= this.capacity) {
expand();
}
this.data[this.top++] = data;
return true;
}
public static void main(String[] args) {
StackV1 stack = new StackV1();
for (int i = 0; i < 20; i++) {
stack.push("test" + i);
}
for (int i = 0; i < 20; i++) {
System.out.println("isEmpty:" + stack.isEmpty() + ":" + stack.pop());
}
System.out.println("isEmpty:" + stack.isEmpty() + ":" + stack.pop());
}
二、V2版本
2.1 功能简介
- 栈的基本功能满足
- 可扩容
- 使用Optional返回数据
- 完成迭代器扩展
2.2 代码
注意:增加迭代器,对于栈的功能没有帮助
public class StackV2 implements stack, Iterable {
private int top;
private int capacity = DEFAULT_SIZE;
private double expand = DEFAULT_EXPAND;
private static final int DEFAULT_SIZE = 16;
private static final double DEFAULT_EXPAND = 1.5;
Object[] data = new Object[DEFAULT_SIZE];
public StackV2() {
}
public StackV2(int capacity) {
if (capacity > 16) {
this.data = new Object[capacity];
}
}
public StackV2(int capacity, double expand) {
this.capacity = capacity;
this.expand = expand;
if (capacity > 16) {
this.data = new Object[capacity];
}
}
private void expand() {
this.capacity *= this.expand;
// 复制数组
this.data = Arrays.copyOf(this.data, this.capacity);
}
@Override
public int size() {
return this.top;
}
@Override
public boolean isEmpty() {
return this.top == 0;
}
@Override
public void clear() {
this.top = 0;
}
@Override
public Optional<Object> pop() {
if (this.top <= 0) {
return Optional.empty();
}
return Optional.of(this.data[--this.top]);
}
@Override
public Optional<Object> peek() {
if (this.top <= 0) {
return Optional.empty();
}
return Optional.of(this.data[this.top - 1]);
}
@Override
public boolean push(Object data) {
if (this.top >= this.capacity) {
expand();
}
this.data[this.top++] = data;
return true;
}
public static void main(String[] args) {
StackV2 stack = new StackV2();
for (int i = 0; i < 20; i++) {
stack.push("test" + i);
}
for (Object data : stack) {
System.out.println("data:" + data);
}
}
@Override
public Iterator iterator() {
return new ArrayIterator();
}
private class ArrayIterator implements Iterator<Object> {
private int j = 0;
private boolean removable = false;
public boolean hasNext() {
return j < top;
}
public Object next() throws NoSuchElementException {
if (j == top) throw new NoSuchElementException("No next element");
removable = true;
return data[j++];
}
public void remove() throws IllegalStateException {
if (!removable) throw new IllegalStateException("nothing to remove");
StackV2.this.pop();
j--;
removable = false;
}
}
}
三、V3版本
2.1 功能简介
- 栈的基本功能满足
- 可扩容
- 使用Optional返回数据
- 完成迭代器扩展
- 支持泛型
2.2 代码
注意:模仿ArrayList返回数据时才强转类型
public interface Istack<T> {
int size();
boolean isEmpty();
void clear();
Optional<T> pop();
Optional<T> peek();
boolean push(T data);
}
public class StackV3<T> implements Istack<T>, Iterable<T> {
private int top;
private int capacity = DEFAULT_SIZE;
private double expand = DEFAULT_EXPAND;
private static final int DEFAULT_SIZE = 16;
private static final double DEFAULT_EXPAND = 1.5;
Object[] data = new Object[DEFAULT_SIZE];
public StackV3() {
}
public StackV3(int capacity) {
if (capacity > 16) {
this.data = new Object[capacity];
}
}
public StackV3(int capacity, double expand) {
this.capacity = capacity;
this.expand = expand;
if (capacity > 16) {
this.data = new Object[capacity];
}
}
private void expand() {
this.capacity *= this.expand;
// 复制数组
this.data = Arrays.copyOf(this.data, this.capacity);
}
@Override
public int size() {
return this.top;
}
@Override
public boolean isEmpty() {
return this.top == 0;
}
@Override
public void clear() {
this.top = 0;
}
@Override
public Optional<T> pop() {
if (this.top <= 0) {
return Optional.empty();
}
return Optional.of((T) this.data[--this.top]);
}
@Override
public Optional<T> peek() {
if (this.top <= 0) {
return Optional.empty();
}
return Optional.of((T) this.data[this.top - 1]);
}
@Override
public boolean push(T data) {
if (this.top >= this.capacity) {
expand();
}
this.data[this.top++] = data;
return true;
}
public static void main(String[] args) {
StackV3<String> stack = new StackV3<>();
for (int i = 0; i < 20; i++) {
stack.push("test" + i);
}
stack.forEach(data -> {
System.out.println("forEach-data:" + data);
});
for (Object data : stack) {
System.out.println("for-data:" + data);
}
}
@Override
public Iterator iterator() {
return new ArrayIterator();
}
private class ArrayIterator implements Iterator<T> {
private int j = 0;
private boolean removable = false;
public boolean hasNext() {
return j < top;
}
public T next() throws NoSuchElementException {
if (j == top) throw new NoSuchElementException("No next element");
removable = true;
return (T) data[j++];
}
public void remove() throws IllegalStateException {
if (!removable) throw new IllegalStateException("nothing to remove");
StackV3.this.pop();
j--;
removable = false;
}
}
}