前言
开发过程中经常会用到集合,在不用思考的情况下,集合我们肯定是用ArrayList,HashMap,特别点的时候会用到 HashSet。但是,这几个集合类真的是万能的么?针对不同的开发场景,我们需要怎样选择正确的集合呢?那么,这节我们就将一个特别的集合----- Stack,它有一个响亮并且我们不陌生的名字:栈!
今天涉及的知识有:
- Stack 原理
- Stack 的使用
- Stack 和 ArrayList 的区别
- 使用示例及结果
一.Stack 原理
首先看段源码:
public class Stack<E> extends Vector<E> {
由此知道 Stack 继承自 Vector,Vector是个什么鬼,接触不多,但我们大概知道它跟 ArrayList 似乎有那么点关系(因为面试的时候会涉及到),具体啥关系,不清楚,那么接着看源码:
public class Vector<E>extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
这里,我们知道了两点:
- Vector 是 AbstractList 子类
- Vector 实现了 List 接口
ok,让我们再稍微追溯下 ArrayList 源码:
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
ArrayList 是 List 的一个实现类,这大家都清楚,关键是这里我们知道了一个信息:ArrayList 是 AbstractList 子类
那么,ArrayList 和 Vector 关系总算清楚了,他们是哥们关系,并且都继承自 AbstractList
从上面所有的分析,我们知道了Stack 本质也是一个 List。其具备 List 所有方法。
然后,我们需要了解的是,Stack 栈是一个 "先进后出"的原理。
那么基于以上,我们需要记住的是:
-
Stack 栈是一个 "先进后出"的原理
-
Stack 本质是一个List,其具备 List 所有方法
二.Stack 的使用
2.1 初始化
Stack stack=new Stack();
2.2 判断Stack是否为空
isEmpty()
2.3 添加元素
push(E item)
我们知道 Stack 也是一个List,而List的添加是 add(E e),那么Stack的 push 和 add 方法有啥不同呢?
下面先看 源码中Stack 的add方法:
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
Stack 中push方法的源码:
public E push(E item) {
addElement(item);
return item;
}
追溯 addElement(item) 方法:
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
}
发现了没?原来stack的push方法最后调用的和stack的add方法是同一个方法,即push调用的其实还是 add方法。
2.4 获取栈顶值,元素不出栈(栈为空时抛异常)
peek()
这里需要注意的是,stack调用peek后,item还是在栈中的,并未被移除,然后在调用peek时要判断stack中是否有元素,否则会引发异常
2.5 是否存在obj
search(Object obj)
返回值为int,若存在,返回值为obj距离栈顶的位置,若不存在,返回 -1
2.6 移除栈顶
pop()
此方法是移除栈顶的元素,并且返回值是移除的item
2.7 其他方法
stack 作为 list,具备 list 常用方法,如:
//获取stack长度
size()
//下标处添加
add(int index, E element)
//添加集合
addAll(Collection<? extends E> c)
//移除对象
remove(Object obj)
//根据下标移除对象
remove(int index)
//清空
clear()
其他关于 list 的方法,这里就不多讲了。
2.8 Stack的通常操作
- push 入栈
- pop 栈顶元素出栈,并返回
- peek 获取栈顶元素,并不删除
三. Stack 和 ArrayList 的区别
stack 和 ArrayList 的最大区别是 stack 是线程安全的,而 ArrayList 不是线程安全的。所以,当涉及到多线程问题的时候,优先考虑使用 stack
四.使用示例及结果
调用代码如下:
public static void main(String []args){
System.out.println("我是主函数");
Stack stack=new Stack();
// stack.isEmpty();//栈是否为空
// stack.push("A");//进栈
// stack.peek();//获取栈顶值,元素不出栈
// stack.pop();//栈顶元素出栈
// stack.search("pp");
System.out.println("====stack是否为空====="+stack.isEmpty());
//添加
stack.push("A");//进栈
stack.push("b");//进栈
stack.push("c");//进栈
//长度
System.out.println("====stack==size==1==="+stack.size());
//获取栈顶值,元素不出栈(栈为空时抛异常)
if(stack!=null&&!stack.isEmpty()) {
System.out.println("====stack==topValue=====" + stack.peek());
}
//长度
System.out.println("====stack==size==2==="+stack.size());
//找下标
System.out.println("====stack===========index==="+stack.search("A"));
//移除栈顶
Object obj=stack.pop();
System.out.println("====stack==pop==obj="+obj);
//长度
System.out.println("====stack==size==3==="+stack.size());
}
返回结果:
我是主函数
====stack是否为空=====true
====stack==size==1===3
====stack==topValue=====c
====stack==size==2===3
====stack===========index===3
====stack==pop==obj=c
====stack==size==3===2
ok,今天关于 stack的内容就讲到这里了,谢谢大家。