Java 集合操作之Queue 集合

简介

Queue 用于模拟队列这种数据结构,队列通常是指“先进先出”(FIFO)的容器。新元素插入(offer)到队列的尾部,访问元素(poll)操作会返回队列头部的元素。通常,队列不允许随机访问队列中的元素。

Queue 接口中定义了如下几个重要的方法:

  • void add(Object e):将指定元素加入此队列的尾部。
  • Object element():获取队列头部的元素,但是不删除该元素。
  • boolean offer(Object e):将指定元素加入到此队列的尾部。当使用有容量限制的队列时,此方法通常比 add(Object e)方法更好。
  • Object peek():获取队列头部的元素,但是不删除该元素。如果此队列为空,则返回 null。
  • Object poll():获取队列头部的元素,并删除该元素。如果此队列为空,则返回 null。
  • Object remove():获取队列头部元素,并删除该元素。

Queue 实现类

Queue 接口有一个 PriorityQueue 实现类。另外,Queue 还有一个 Deque 接口,Deque 代表一个“双端队列”,双端队列可以同时从两端来添加、删除元素。因此 Deque 的实现类既可以当成队列使用,可以当成栈使用。Deque 提供了 ArrayDeque 和 LinkedList 两个实现类。

PriorityQueue

PriorityQueue 保存队列元素的顺序并不是按加入队列的顺序,而是按队列元素的大小进行重新排序。因此当调用 peek() 方法或者 poll() 方法取出队列中的元素时,并不是取出最先进入队列的元素,而是取出队列中最小的元素。

import java.util.PriorityQueue;

public class QueueTest {

	public static void main(String[] args) {

		PriorityQueue<Integer> queue = new PriorityQueue<>();

		// 下面代码依次想 queue 中添加元素
		queue.offer(6); // 向容器的尾部添加元素
		queue.offer(-3);

		queue.offer(20);
		queue.offer(18);

		// 输出队列
		System.out.println(queue); // 输出结果:[-3, 6, 20, 18]
		System.out.println("====================");

		for (int i = 0, length = queue.size(); i < length; i++) {
			System.out.println(queue.poll()); // -3 6 18 20
		}
	}
}

运行上面的程序之后可以看到:

  1. 直接输出 PriorityQueue,队列没有很好的按照大小排序,这个只是受到 PriorityQueue 的 toString() 方法的返回值影响。

  2. 在程序多次调用 poll() 方法时,数据是按照从小到大的顺序移出队列的

PriorityQueue 排序方式

PriorityQueue 不允许插入 null 元素,他还需要队列元素进行排序,PriorityQueue 的元素有两种排序方式:

  • 自然排序:采用自然顺序的 PriorityQueue 集合的元素必须实现了 Comparable 接口,并且是同一个类的多个实例,否则可能导致 ClassCastException 异常。
  • 定制排序:创建 PriorityQueue 队列时,。传入一个 Comparator 对象,该对象复制对队列中的元素进行排序。采用定制排序时不需要队列实现 Comparable 接口。

Deque 接口与 ArrayDeque 实现类

Deque 接口是 Queue 接口的子接口,它代表一个双端队列。Deque 队列的重要方法如下:

  • void addFirst(Object e):将指定元素插入队列的开头。
  • void addLast(Object e):将指定元素插入队列的末尾。
  • Iterator descendingIterator():返回队列的迭代器,该迭代器将以逆向顺序来迭代队列中的元素。
  • Object getFirst():获取但不删除队列的第一个元素。
  • Object getLast():获取但不删除队列的最后一个元素。
  • boolean offerFirst(Object e):将指定元素插入队列的开头。
  • boolean offerLast(Object e):将指定元素插入队列的末尾。
  • Object peekFirst():获取但不删除队列的第一个元素,如果此队列为空,则返回 null。
  • Object peekLast():获取但不删除队列的最后一个元素,如果此队列为空,则返回 null。
  • Object pollFirst():获取并删除队列的第一个元素,如果此队列为空,则返回 null。
  • Object pollLast():获取并删除队列的最后一个元素,如果此队列为空,则返回 null。
  • void push(Object e)(栈方法):将第一个元素 push 进队列说表示的栈的栈顶,相当于 addFirst(e)。
  • Object removeFirst():获取并删除该队列的第一个元素。
  • Object removeLast():获取并删除该队列的最后一个元素。
  • boolean removeFirstOccurrence(Object o):删除该队列第一次出现的元素 o
  • boolean removeLastOccurrence(Object o):删除该队列最后一次出现的元素 o
Deque 与 Queue 的方法对照
Queue 的方法 Deque 的方法
add(e)/offer(e) addLast(e)/offerLast(e)
remove()/poll() removeFirst()/pollFirst()
element()/peek() getFirst()/peekFirst()
Deque 与 Stack 的方法对照
stack 的方法 Deque 的方法
push(e) addLast(e)/offerLast(e)
pop() removeFirst()/pollFirst()
peek() getFirst()/peekFirst()

将 Deque 当做 “栈”来使用

import java.util.ArrayDeque;

public class DequeTest {

    public static void main(String[] args) {
        ArrayDeque stack = new ArrayDeque();
        stack.push(10);
        stack.push(-3);
        stack.push(20);
        stack.push(18);
        System.out.println(stack);     // 输出结果:[18, 20, -3, 10]

        System.out.println("===============");
        // 访问第一个元素,但是不将其 pop 出 "栈"
        System.out.println(stack.peek());   //  18
        System.out.println(stack);     // 输出结果:[18, 20, -3, 10]

        System.out.println("===============");
        // 访问第一个元素,并将其 pop 出 "栈"
        System.out.println(stack.pop());   //  18
        System.out.println(stack);     // 输出结果:[ 20, -3, 10]
    }
}

控制台输出:

[18, 20, -3, 10]
===============
18
[18, 20, -3, 10]
===============
18
[20, -3, 10]

将 Deque 当做 “队列” 来使用,按照 “先进先出”的方式操作

import java.util.ArrayDeque;

public class DequeTest {

    public static void main(String[] args) {
        ArrayDeque queue = new ArrayDeque();
        queue.offer(10);
        queue.offer(-3);
        queue.offer(20);
        queue.offer(18);
        System.out.println(queue);     // 输出结果:[10, -3, 20, 18]

        System.out.println("===============");
        // 访问第一个元素,但是不将其 pop 出 "栈"
        System.out.println(queue.peek());   //  10
        System.out.println(queue);     // 输出结果:[10, -3, 20, 18]

        System.out.println("===============");
        // 访问第一个元素,并将其 pop 出 "栈"
        System.out.println(queue.pop());   //  10
        System.out.println(queue);     // 输出结果:[-3, 20, 18]
    }
}

详细的说明,可以去参考下面文章的内容
https://www.cnblogs.com/CarpenterLee/p/5488070.html

你可能感兴趣的:(Java,集合)