Queue 队列

  • 简介
  • Queue方法
  • Queue子接口
  • BlockingQueue
  • Deque
  • Deque方法
  • Queue实现类
  • LinkedList


简介

Queue接口与List、Set同一级别,都是继承了Collection接口。

-------| Collection 单例集合的根接口。
------------| List 如果是实现了List接口的集合类,具备的特点: 有序,可重复。
------------| Set 如果是实现了Set接口的集合类,具备特点: 无序,不可重复。
------------| Queue 如果是实现了Queue接口的集合类,具备特点: 模拟队列存储结构,有序,先入先出。

Java的Queue java的Queue类_java

Queue方法

队列是一种数据结构,它有两个基本操作:在队列尾部加入一个元素,和从队列头部移除一个元素。

Queue是java中实现队列的接口,它总共只有6个方法,我们一般只用其中3个就可以了。

Queue的6个方法分类:

  1. 压入元素(添加):add()、offer()
    相同:未超出容量,从队尾压入元素,返回压入的那个元素。
    区别:在超出容量时,add()方法会对抛出异常,offer()返回false
  2. 弹出元素(删除):remove()、poll()
    相同:容量大于0的时候,删除并返回队头被删除的那个元素。
    区别:在容量为0的时候,remove()会抛出异常,poll()返回false
  3. 获取队头元素(不删除):element()、peek()
    相同:容量大于0的时候,都返回队头元素。但是不删除
    区别:容量为0的时候,element()会抛出异常,peek()返回null。

队列除了基本的 Collection 操作外,还提供特有的插入、提取和检查操作(如上)。每个方法都存在两种形式:一种抛出异常(操作失败时),另一种返回一个特殊值(null 或 false,具体取决于操作)。插入操作的后一种形式是用于专门为有容量限制的 Queue 实现设计的;在大多数实现中,插入操作不会失败。

抛出异常

返回特殊值

插入

add(e)

offer(e)

删除

remove()

poll()

检查

element()

peek()

示例:

public class QueueTest {
    public static void main(String[] args) {
        Queue<String> queue = new LinkedList();
        queue.offer("元素A");
        queue.offer("元素B");
        queue.offer("元素C");
        queue.offer("元素D");
        queue.offer("元素E");
        while (queue.size() > 0) {
            String element = queue.poll();
            System.out.println(element);
        }
    }
}

输出:

元素A
元素B
元素C
元素D
元素E

Queue子接口

Queue有三个子接口:BlockingDequeBlockingQueueDeque

BlockingQueue

支持两个附加操作的 Queue,这两个操作是:获取元素时等待队列变为非空,以及存储元素时等待空间变得可用。

Deque

与 List 接口不同,此接口不支持通过索引访问元素。

双端队列:一个线性 collection,支持在两端插入和移除元素。此接口既支持有容量限制的双端队列,也支持没有固定大小限制的双端队列。

此接口定义在双端队列两端访问元素的方法。提供插入、移除和检查元素的方法。每种方法都存在两种形式:一种形式在操作失败时抛出异常,另一种形式返回一个特殊值(null 或 false,具体取决于操作)。插入操作的后一种形式是专为使用有容量限制的 Deque 实现设计的。

下表总结了上述 12 种方法:

第一个元素(头部)

最后一个元素(尾部)

抛出异常

返回特殊值

抛出异常

返回特殊值

插入

addFirst(e)

offerFirst(e)

addLast(e)

offerLast(e)

删除

removeFirst()

pollFirst()

removeLast()

pollLast()

检查

getFirst()

peekFirst()

getLast()

peekLast()

此接口扩展了 Queue 接口。在将双端队列用作队列时,将得到 FIFO(先进先出)行为。将元素添加到双端队列的末尾,从双端队列的开头移除元素。从 Queue 接口继承的方法完全等效于 Deque 方法,如下表所示:

Queue方法

等效Deque方法

add(e)

addLast(e)

offer(e)

offerLast(e)

remove()

removeFirst()

poll()

pollFirst()

element()

getFirst()

peek()

peekFirst()

双端队列也可用作 LIFO(后进先出)堆栈。应优先使用此接口而不是遗留 Stack 类。在将双端队列用作堆栈时,元素被推入双端队列的开头并从双端队列开头弹出。堆栈方法完全等效于 Deque 方法,如下表所示:

堆栈方法

等效Deque方法

push(e)

addFirst(e)

pop()

removeFirst()

peek()

peekFirst()

注意,在将双端队列用作队列或堆栈时,peek 方法同样正常工作;无论哪种情况下,都从双端队列的开头抽取元素。

Deque 实现通常不定义基于元素的 equals 和 hashCode 方法,而是从 Object 类继承基于身份的 equals 和 hashCode 方法。

Deque方法

此接口中提供的方法主要有:

     - add(E e) 添加元素至队列的尾部
     - addFirst(E e) 将指定元素插入此双端队列的开头
     - addLast(E e) 将指定元素插入此双端队列的末尾
     - contains(Object o) 如果此双端队列包含指定元素,则返回 true
     - descendingIterator() 返回以逆向顺序在此双端队列的元素上进行迭代的迭代器
     - element() 获取,但不移除此双端队列所表示的队列的头部
     - getFirst() 获取,但不移除此双端队列的第一个元素。
     - getLast() 获取,但不移除此双端队列的最后一个元素。
     - iterator() 返回以恰当顺序在此双端队列的元素上进行迭代的迭代器。
     - offer(E e) 将指定元素插入此双端队列所表示的队列
     - peek() 获取,但不移除此双端队列所表示的队列的头部
     - poll() 获取并移除此双端队列所表示的队列的头部
     - pop() 从此双端队列所表示的堆栈中弹出一个元素
     - push(E e) 将一个元素推入此双端队列所表示的堆栈
     - remove() 获取并移除此双端队列所表示的队列的头部
     - remove(Object o) 从此双端队列中移除第一次出现的指定元素
     - removeFirst() 获取并移除此双端队列第一个元素
     - removeLast() 获取并移除此双端队列的最后一个元素
     - size() 返回此双端队列的元素数

双端队列的基本方法和 Collection 接口是一样的,如 add(E e) 、contains(Object o)
、remove(Object o) 、 size()。
其他方法就是实现双端队列、堆栈的常用方法。

Queue实现类

Queue的实现类有 LinkedListPriorityQueue 。最常用的实现类是 LinkedList 。

LinkedList

LinkedList 类是List接口的实现类,但是同时也是 Deque 接口实现类,所以 LinkedList 既可以当做 双端队列 来使用,也可以当做 来使用。

//使用LinkedList模拟队列的存储方式
class TeamList{
        
        LinkedList list;
        
        public TeamList(){
                list = new LinkedList();
        }
        
        public void add(Object o){
                list.offer(o);
        }
        
        public Object remove(){
                return list.poll();
        }
        
        //获取元素个数
        public int size(){
                return list.size();
        }
}

public class Demo9 {
        public static void main(String[] args) {
                TeamList list=  new TeamList();
                list.add("李嘉诚");
                list.add("马云");
                list.add("王健林");
        
                int size = list.size();
                for(int i = 0 ; i<size ; i++){
                        System.out.println(list.remove());
                }
        }
}

LinkedList 是采用 链表 的形式实现的,LinkedList 因此比较适合用于经常插入和删除的操作,而以数组实现的更加适合于随机访问。