1.概述
Queue在java中是一个接口,规定了一些队列实现的基本操作。Queue是一个队列,先进先出。他有一个子接口是Deque,是一个双端队列。可以在两端进行进出操作。
本文着重比较java.util包下实现这两个接口的类的特点。
首先来看看java.util包下有哪些实现这两个接口的类。
- ArrayDeque
- LinkedList
- PriorityQueue
2.特点
2.1 ArrayDeque
ArrayDeque采用了循环数组的方式来完成双端队列的功能。
- 当头尾索引相遇的时候,两倍扩容
- 非线程安全的,不支持并发访问和修改。
- 支持fast-fail.
- 作为栈使用的话比比栈要快.
- 当队列使用比linklist要快。
- 不允许null值
- 对头尾添加删除元素效率很高。但是删除中间元素的话,需要拷贝数组。拷贝头和尾距离删除元素位置近的那一段,为了提高效率。
- 默认数组大小是8
2.2 LinkedList
之前的博客做过详细的介绍,可以参考博客JDK解析—LinkedList
这里就说一下它的特点
- 是基于节点实现的双向链表的 List ,每个节点都指向前一个和后一个节点从而形成链表。
- 因为可以对两端进行操作,所以可以实现队列、栈的功能。
- 添加、删除元素效率高,不需要像ArrayDeque一样拷贝数组。只需要修改相应的指针即可。
- 不存在容量的问题。
2.3 PriorityQueue
优先级队列,可以看作是一个堆的实现,默认是最小堆,若要使用最大堆则需要传入自定义的比较器。
特点:
- 底层数组实现,默认大小11
- 不能存储null值
- 线程不安全。可以使用java.util.concurrent.PriorityBlockingQueue(线程安全)
- 当遍历一个 PriorityQueue 时,没有任何顺序保证
- 通过判断如果需要扩容,先扩容,再插入。【数组容量满了之后才会触发扩容】。若旧容量 小于64 则 新的容量为 原来容量的两倍+2。若大于64 则 扩容为原来的1.5倍
- 使用比较器,或插入的元素实现了Comparable接口。