什么是Queue集合?java
答:Queue用于模拟队列这种数据结构。队列一般是指“先进先出(FIFO)”的容器。队列的头部保存在队列中存放时间最长的元素,尾部保存存放时间最短的元素。新元素插入到队列的尾部,取出元素会返回队列头部的元素。一般,队列不容许随机访问队列中的元素。数组
Queue接口中定义了以下的几个方法:数据结构
void add(Object e): 将指定元素插入到队列的尾部。性能
object element(): 获取队列头部的元素,可是不删除该元素。spa
boolean offer(Object e): 将指定的元素插入此队列的尾部。当使用容量有限的队列时,此方法一般比add(Object e)有效。 线程
Object peek(): 返回队列头部的元素,可是不删除该元素。若是队列为空,则返回null。3d
Object poll(): 返回队列头部的元素,并删除该元素。若是队列为空,则返回null。指针
Object remove(): 获取队列头部的元素,并删除该元素。code
Queue接口有一个PriorityQueue实现类。除此以外,Queue还有一个Deque接口,Deque表明一个“双端队列”,双端队列能够同时从两端删除或添加元素,所以Deque能够看成栈来使用。java为Deque提供了ArrayDeque实现类和LinkedList实现类。对象
1.PriorityQueue实现类
PriorityQueue是一种比较标准的队列实现类,而不是绝对标准的。这是由于PriorityQueue保存队列元素的顺序不是按照元素添加的顺序来保存的,而是在添加元素的时候对元素的大小排序后再保存的。所以在PriorityQueue中使用peek()或pool()取出队列中头部的元素,取出的不是最早添加的元素,而是最小的元素。
public class PriorityQueueTest { public static void main(String[] args){ PriorityQueue pq = new PriorityQueue(); pq.offer(6); pq.add(-3); pq.add(20); pq.offer(18); //输出:[-3, 6, 20, 18] System.out.println(pq); } }
PriorityQueue不容许插入null元素,它还须要对队列元素进行排序,PriorityQueue有两种排序方式:
天然排序:采用天然排序的PriorityQueue集合中的元素必须实现Comparator接口,并且应该是一个类的多个实例,不然可能致使ClassCastException异常。
定制排序:建立PriorityQueue队列时,传入一个Comparable对象,该对象负责对全部队列中的全部元素进行排序。采用定制排序不要求必须实现Comparator接口。
2.Dueue接口与ArrayDeque实现类
Deque接口是Queue接口的子接口,它表明一个双端队列,Deque定义了一些方法:
void addFirst(Object e): 将指定元素添加到双端队列的头部。
void addLast(Object e): 将指定元素添加到双端队列的尾部。
Iteratord descendingItrator(): 返回该双端队列对应的迭代器,该迭代器以逆向顺序来迭代队列中的元素。
Object getFirst(): 获取但不删除双端队列的第一个元素。
Object getLast(): 获取但不删除双端队列的最后一个元素。
boolean offFirst(Object e): 将指定元素添加到双端队列的头部。
boolean offLast(OBject e): 将指定元素添加到双端队列的尾部。
Object peekFirst(): 获取但不删除双端队列的第一个元素;若是双端队列为空,则返回null。
Object PeekLast(): 获取但不删除双端队列的最后一个元素;若是双端队列为空,则返回null。
Object pollFirst(): 获取并删除双端队列的第一个元素;若是双端队列为空,则返回null。
Object pollLast(): 获取并删除双端队列的最后一个元素;若是双端队列为空,则返回null。
Object pop()(栈方法): pop出该双端队列所表示的栈的栈顶元素。至关于removeFirst()。
void push(Object e)(栈方法): 将一个元素push进该双端队列所表示的栈的栈顶。至关于addFirst()。
Object removeFirst(): 获取并删除该双端队列的第一个元素。
Object removeFirstOccurence(Object o): 删除该双端队列的第一次出现的元素o。
Object removeLast(): 获取并删除该双端队列的最后一个元素o。
Object removeLastOccurence(Object o): 删除该双端队列的最后一次出现的元素o。
public class ArrayDequeTest { public static void main(String[] args){ ArrayDeque queue = new ArrayDeque(); queue.offer("春"); queue.offer("夏"); queue.offer("秋"); //输出:[春, 夏, 秋] System.out.println(queue); //输出:春 System.out.println(queue.peek()); //输出:[春, 夏, 秋] System.out.println(queue); //输出:春 System.out.println(queue.poll()); //输出:[夏, 秋] System.out.println(queue); } }
//将双端队列当作栈 public class DequeStack { public static void main(String[] args){ ArrayDeque stack = new ArrayDeque(); stack.push("春"); stack.push("夏"); stack.push("秋"); //输出:[秋, 夏, 春] System.out.println(stack); //输出:秋 System.out.println(stack.peek()); //输出:[秋, 夏, 春] System.out.println(stack); //输出:秋 System.out.println(stack.pop()); //输出:[夏, 春] System.out.println(stack); } }
3.LinkedList实现类
LinkedList是List接口的实现类,所以它能够是一个集合,能够根据索引来随机访问集合中的元素。此外,它仍是Duque接口的实现类,所以也能够做为一个双端队列,或者栈来使用。
LinkedList与ArrayList,ArrayDeque的实现机制彻底不一样,ArrayList和ArrayDeque内部以数组的形式来保存集合中的元素,所以随机访问集合元素时有较好的性能;而LinkedList以链表的形式来保存集合中的元素,所以随机访问集合元素时性能较差,可是插入和删除元素时性能比较出色(只需改变指针所指的地址便可),须要指出的是,虽然Vector也是以数组的形式来存储集合但由于它实现了线程同步(并且实现的机制很差),故各方面的性能都比较差。