Stack是Vector的子类,它用于模拟“棧”这种数据结构,“棧”通常是指“后进先出”(LIFO)的容器。最后“push”进棧的元素,将最先被“pop”出棧。进棧出棧的都是Object,因此从棧中取出元素后必须进行类型转换。
Stack提供方法:
由于Stack集成了Vector,因此它也是一个非常古老的Java集合类,它同样是线程安全的、性能较差,因此尽量少用Stack类。如果需要请用ArrayDeque。
ArrayDeque 是List的实现类,ArrayDeque既实现了List接口,也实现了Deque接口,由于实现的Deque接口,因此可以作为棧来使用;而且ArrayDeque 底层也是基于数组的实现,因此性能也很好。
Queue用于模拟队列这种数据结构,队列通常是指“先进先出”(FIFO)的容器。
队列的头部保存在队列中存放时间最长的元素,队列的尾部保存在队列中存放时间最短的元素。新元素插入(offer)到队列的尾部,访问元素(poll)操作会返回队列头部的元素。
注意,队列不允许随机访问队列中的元素。
Queue解耦中定义了如下方法:
Object remove()
获取队列的头部元素,并删除该元素。
列表内容
Queue解耦只有一个PriorityQueue实现类。除此之外,Queue还有一个Deque接口,
Deque代表一个“双端队列”,双端队列可以同事对两端来添加、删除元素,因此Deque的实现类既可当成队列使用,也可当成棧使用。
PriorityQueue是一个比较标准的队列实现类。之所以说它是比较标准的队列实现类,而不是绝对标准的队列实现类,是因为PriorityQueue保存队列元素顺序并不是按加入队列的顺序,而是按队列元素大小进行重新排序。因此嗲用peek()方法或poll()方法取出队列中元素时,并不是取出最先进入队列的元素,而是取出队列中最小的元素。
注意:PriorityQueue已经违反了队列的最基本规则:先进先出(FIFO)。
示例:
package com.queue;
import java.util.PriorityQueue;
public class QueueOrDueueTest {
public static void main(String[] args) {
PriorityQueue queue = new PriorityQueue();
queue.offer(2);
queue.offer(12);
queue.offer(-2);
queue.offer(5);
System.out.println(queue);//[-2, 5, 2, 12]
System.out.println(queue.poll());//访问第一个其实是访问最小的一个 -2
System.out.println(queue.poll());//2
System.out.println(queue.poll());//5
System.out.println(queue);//[12]
}
}
程序多次调用queue.poll()方法,即可看到元素按从小到大的顺序“移出队列”。
自然排序:
采用自然数需的PriorityQueue 集合中的元素必须实现Comparable接口,而且应该是同一类的多个实例,否则抛出ClassCaseException。
定制排序:
创建PriorityQueue 队列时,传入一个Comparator对象,该对象负责队列中的所有元素进行排序。采用定制排序时不需要队列元素实现Comparable接口。
Deque接口是Queue接口的子接口,它代表一个双端队列,Deque接口里定义了一些双端队列的方法,这些方法允许从两端来操作队列的元素。
注意:
ArrayDeque,它是基于数组实现的双端队列,创建Deque是同样可指定一个numElements参数,该参数用于指定Object[]数组的长度;如果不指定numElements参数 ,Deque底层数组长度为16。
ArrayDeque作为棧
程序中需要使用“棧”这种数据结构时,推荐使用ArrayDeque,尽量避免使用Stack(太古老,性能差)。
示例:
package com.queue;
import java.util.ArrayDeque;
public class ArrayDequeTest {
public static void main(String[] args) {
ArrayDeque stack = new ArrayDeque();
stack.push("JAVA");
stack.push("JS");
stack.push("C++");
System.out.println(stack);
//输出:[C++, JS, JAVA]
//访问第一个元素,但不将其弹出棧
System.out.println(stack.peek());
//输出:C++
System.out.println(stack.pop());
//输出:C++
System.out.println(stack);
//输出:[JS, JAVA]
}
}
ArrayDeque作为队列
按照“先进先出”的方式操作集合元素
示例:
public static void main(String[] args) {
ArrayDeque queue = new ArrayDeque();
queue.offer("JAVA");
queue.offer("JS");
queue.offer("C++");
System.out.println(queue);
//输出:[JAVA, JS, C++]
//访问队列头部元素,但不将其poll出队列"棧",输出:JAVA
System.out.println(queue.peek());
//poll出第一个元素,输出:JAVA
System.out.println(queue.poll());
System.out.println(queue);
//输出:[JS, C++]
}