七,Java集合类(5)——Queue接口及其实现类

时间:2022-07-13 17:03:20

Queue集合

Queue用于模拟队列数据结构,采用“先进先出”的方式。Queue接口是继承了Collection的接口,而Queue接口下面的实现类是PriorityQueue,继承的接口是Deque,接口Deque接口的实现类是ArrayDeque,同时Deque还被LinkedList类实现。

框架结构如下图中红色区域:
七,Java集合类(5)——Queue接口及其实现类

PriorityQueue实现类

PriorityQueue是一个比较标准的队列实现类。之所以是比较标准的原因是PriorityQueue保存队列元素的顺序并不是按照加入队列的顺序,而是按照队列元素的大小进行重新排序。因此当调用peek()或者是poll()的方法取出队列中的元素通常都是最小的元素。值得注意的是

peek()方法取出队列头部元素时候,不删除该元素,而poll()方法取出元素时会删除元素。如果遇到队列为空的情况是,两者都会返回null

package com.practice.collection;

import java.util.PriorityQueue;

public class PriorityQueueTest {

public static void main(String[] args) {
PriorityQueue priorityQueue = new PriorityQueue();
priorityQueue.offer(6);
priorityQueue.offer(-3);
priorityQueue.offer(20);
priorityQueue.offer(18);
System.out.println(priorityQueue);
while(!priorityQueue.isEmpty()){

System.out.println(priorityQueue.poll());
}
}
}

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

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

Deque接口

Deque接口是Queue接口的子接口,代表一个双端队列。同时Deque不仅可以作为双端队列使用,而且可以被当成栈来使用,所以可以使用出栈,入栈的方法。

程序示例将ArrayDeque当做“栈”来操作

package com.practice.collection;

import java.util.ArrayDeque;

public class ArrayDequeStack {

public static void main(String[] args) {
ArrayDeque stack = new ArrayDeque();
stack.push(2);
stack.push(5);
stack.push(7);
stack.push(12);
System.out.println(stack);
/**
* peek(),element()该方法获取队列头部的元素,但是不删除该元素。
* poll()该方法也是获取队列头部的元素,但是删除该元素。
*/
System.out.println(stack.peek());
System.out.println(stack);
System.out.println(stack.pop());
System.out.println(stack);
}
}

程序示例将ArrayDeque当做“队列”来操作

package com.practice.collection;

import java.util.ArrayDeque;

public class ArrayDequeQueue {

public static void main(String[] args) {
ArrayDeque queue = new ArrayDeque<>();
queue.offer("JAVA SE");
queue.offer("JAVA EE");
queue.offer("ORACLE 11G");
queue.offer("NODE.JS");
System.out.println(queue);
System.out.println(queue.peek());
System.out.println(queue);
System.out.println(queue.poll());
System.out.println(queue);
}
}

LinkedList实现类

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

package com.practice.collection;

import java.util.LinkedList;

public class LinkedListTest {

public static void main(String[] args) {
LinkedList books = new LinkedList<>();
books.offer("疯狂Java讲义");
books.push("企业级应用");
books.offerFirst("疯狂Android讲义");
for(int i = 0;i < books.size();i ++){
System.out.println("遍历中:"+books.get(i));
}
System.out.println(books.peekFirst());
System.out.println(books.peekLast());
System.out.println(books);
System.out.println(books.pollLast());
System.out.println(books);
}
}

LinkedList与ArrayList,ArrayDeque的底层实现方式不同,ArrayList,ArrayDeque使用数组的形式来保存集合中的元素;LinkedList是采用链表的形式实现的,LinkedList因此比较适合用于经常插入和删除的操作,而以数组实现的更加适合于随机访问。

List集合总结

  1. 如果需要遍历List集合元素,对于ArrayList,Vector集合,应该使用随机访问方法(get)来遍历集合元素,对于LinkedList,应该使用迭代器的方式来遍历。
  2. 经常插入和删除的操作来改变集合的大小,可以考虑使用LinkedList集合。使用ArrayList,Vector会经常性的重新分配内部数组的大小,效果较差。
  3. 如果在多线程的情况下使用,可以考虑使用Collections将集合包装成线程安全的集合。