0
点赞
收藏
分享

微信扫一扫

Java学习笔记一Queue集合


Queue用于模拟队列数据结构,先进先出的容器。队列头部保存在队列中存放时间最长的元素,队列的尾部保存在队列中存放时间最短的元素。新元素插入(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接口有一个PriorityQueue实现类。除此之外,Queue还有一个Deque接口,Deque代表一个双端队列,双端队列可以同时从两端来添加、删除元素,因此Deque的实现类既可当成队列使用,也可当栈使用。Java为Deque提供了ArrayDeque和LinkedList两个实现类。

PriorityQueue实现类

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

import java.util.PriorityQueue;
public class PriorityQueueTest {
public static void main(String[] args) {
PriorityQueue pq = new PriorityQueue();
pq.offer(6);
pq.offer(-3);
pq.offer(20);
pq.offer(18);
// 输出pq队列,并不是按元素的加入顺序排列
System.out.println(pq);
// 访问队列的第一个元素,其实就是队列中最小的元素
System.out.println(pq.poll());
}
}

Java学习笔记一Queue集合_数组


直接输出可能看到该队列里的元素并没有很好地按大小进行排序,但这只是受到PriorityQueue的toString()方法的返回值的影响。

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

ArrayDeque实现类

Deque接口提供了一个典型的实现类:ArrayDeque,它是一个基于数组实现的双端队列,创建Deque时同样可指定一个numElements参数,该参数用于指定Object[]数组的长度;如果不指定numElements参数,Deque底层数组的长度为16。
ArrayList和ArrayDeque两个集合类的实现机制基本相似,它们的底层都采用一个动态的、可重分配的Object[]数组来存储集合元素,当集合元素超出了该数组的容量时,系统会在底层重新分配一个Object[]数组来存储集合元素。

ArrayDeque stack = new ArrayDeque();
// 依次将三个元素push入栈
stack.push("疯狂Java讲义");
stack.push("轻量级Java EE企业应用实战");
stack.push("疯狂Android讲义");
System.out.println(stack);
// 访问第一个元素,但不将其pop出栈
System.out.println(stack.peek());
System.out.println(stack);
// pop出第一个元素
System.out.println(stack.pop());
System.out.println(stack);

Java学习笔记一Queue集合_数组_02

LinkedList实现类

LinkedList类是LIst接口的实现类,可以根据索引来随机访问集合中的元素。除此之外,LinkedList还实现了Deque接口,可以被当成双端队列来使用,因此既可以被当作栈来使用,也可以当成队列使用。

= new LinkedList();
// 将字符串元素加入队列的尾部
books.offer("疯狂Java讲义");
// 将字符串元素加入栈的顶部
books.push("轻量级Java EE企业应用实战");
// 将字符串元素添加到队列的头部(相当于栈的顶部)
books.offerFirst("疯狂Android讲义");
//以List的方式(按索引访问的方式)来遍历集合元素
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.pop());
//下面输出将看到队列中第一个元素被删除
System.out.println(books);
//访问并删除队列的最后一个元素
System.out.println(books.pollLast());
System.out.println(books);

Java学习笔记一Queue集合_双端队列_03


LinkedList与ArrayList、ArrayDeque的实现机制完全不同,ArrayList、ArrayDeque内部以数组的形式来保存集合中的元素,因此随机访问集合元素时有较好的性能;而LinkedList内部以链表的形式来保存集合中的元素,因此随机访问集合时性能较差,但在插入、删除元素时性能比较出色(只需改变指针所指的地址即可)。虽然Vector也是以数组的形式来存储集合元素的,但因为它实现了线程同步功能(而且实现机制也不好),所以各方面性能都比较差。


举报

相关推荐

0 条评论