1 package Stack;
2
3 import java.util.*;
4 import java.util.concurrent.atomic.AtomicInteger;
5 import java.util.function.Consumer;
6
7 /**
8 * @program: Study
9 * @description: 手写堆栈,实现堆栈功能并实现堆栈自定义迭代遍历接口
10 * @param:
11 * @author: Hanson
12 * @create: 2020-10-09 20:50
13 **/
14 public class TestStack<R>{
15
16 //Object数组 保存栈数据信息
17 private Object [] data;
18
19 //栈顶指针,默认-1.即栈未初始化,原子类,解决自增自减原子性问题
20 private AtomicInteger top = new AtomicInteger(-1);
21
22 //默认栈容量
23 private static int capacity = 4;
24
25 //构造初始化
26 public TestStack(){
27 this(capacity);
28 }
29 //有参构造初始化
30 public TestStack(int size){
31 if (size > 0) this.data = new Object[size];
32 else this.data = new Object[capacity];
33 }
34 //入栈
35 public R push(R obj){
36 if (data == null || isFull()) resize();
37 data[top.incrementAndGet()] = obj;
38 return obj;
39 }
40 //出栈
41 public R pop(){
42 if (isEmpty()) {
43 data = new Object[capacity];//恢复为栈原始容量,也可以置空,随意就好
44 // throw new RuntimeException("栈空异常");//根据情况选择抛出异常或者返回空元素
45 return null;
46 }
47 R obj = (R) data[top.get()];
48 data[top.get()] = null;//清理元素,防止内存溢出
49 top.decrementAndGet();//栈顶 - 1
50 return obj;
51 }
52 //扩容
53 public void resize(){
54 if (data == null) {
55 data = new Object[capacity];//延时初始化,如果没有上面的无参构造,一定要写这里!!!
56 return;
57 }
58 Object[] newData = new Object[(top.get() + 1)<<1];
59 if (top.get() + 1 >= 0) System.arraycopy(data, 0, newData, 0, top.get() + 1);
60 data = newData;
61 }
62 //栈空?
63 public boolean isEmpty(){
64 return top.get() < 0;
65 }
66 //栈满?
67 public boolean isFull(){
68 return top.get() + 1 >= size();
69 }
70
71 //栈大小
72 public int size(){
73 return data.length;
74 }
75 //栈元素个数
76 public int getSize(){
77 return top.get() + 1;
78 }
79 //获取栈索引元素
80 public R elementData(int index){
81 return (R) data[index];
82 }
83
84 //自定义迭代接口
85 private interface StackEnumeration<R>{
86 boolean hasMoreElements();
87 R nextElement();
88 default StackIterator<R> asIterator(){
89 return new StackIterator<>() {
90 @Override
91 public boolean hasNext() {
92 return hasMoreElements();
93 }
94
95 @Override
96 public R next() {
97 return nextElement();
98 }
99 };
100 }
101 }
102 //自定义迭代器接口
103 private interface StackIterator<R>{
104 boolean hasNext();
105 R next();
106 default void forEachRemaining(Consumer<? super R> action){
107 Objects.requireNonNull(action);
108 while (hasNext()){
109 action.accept(next());
110 }
111 }
112 }
113 //自定义迭代方法
114 public StackEnumeration<R> elements(boolean flag){
115 if (!flag)
116 return new StackEnumeration<R>() {
117 int count = top.get();
118 @Override
119 public boolean hasMoreElements() {
120 return count >= 0;
121 }
122
123 @Override
124 public R nextElement() {
125 synchronized (TestStack.this){
126 if (count >= 0){
127 return elementData(count--);//反向迭代FILO
128 }
129 throw new NoSuchElementException("没有元素");
130 }
131 }
132
133 };
134 else
135 return new StackEnumeration<R>() {
136 int count = 0;
137 @Override
138 public boolean hasMoreElements() {
139 return count < getSize();
140 }
141
142 @Override
143 public R nextElement() {
144 synchronized (TestStack.this){
145 if (count <= getSize()){
146 return elementData(count++);//正向迭代,FIFO
147 }
148 throw new NoSuchElementException("没有元素");
149 }
150 }
151
152 };
153 }
154
155 public static void main(String[] args){
156 TestStack<Integer> stack = new TestStack<Integer>();
157 stack.push(1);
158 stack.push(2);
159 stack.push(3);
160 stack.push(4);
161 stack.push(5);
162 System.out.println("=============入栈==============");
163 System.out.println("isFull? -->" + stack.isFull());
164 System.out.println("栈元素个数: -->" + stack.getSize());
165 System.out.println("栈大小:" + stack.size());
166 System.out.println("isEmpty?-->" + stack.isEmpty());
167 System.out.println("=============出栈==============");
168 System.out.println("出栈元素:" + stack.pop());
169 System.out.println("出栈元素:" + stack.pop());
170 System.out.println("出栈元素:" + stack.pop());
171 System.out.println("出栈元素:" + stack.pop());
172 System.out.println("出栈元素:" + stack.pop());
173 System.out.println("出栈元素:" + stack.pop());
174 System.out.println("isFull? -->" + stack.isFull());
175 System.out.println("栈元素个数: -->" + stack.getSize());
176 System.out.println("栈大小:" + stack.size());
177 System.out.println("isEmpty?-->" + stack.isEmpty());
178 System.out.println("==============正向迭代遍历栈元素FIFO=================");
179 stack.push(1);
180 stack.push(2);
181 stack.push(3);
182 stack.elements(true).asIterator().forEachRemaining(System.out::println);
183 System.out.println("==============反向迭代遍历栈元素FILO=================");
184 stack.elements(false).asIterator().forEachRemaining(System.out::println);
185 }
186 }