之前对Queue只有一知半解,常用它的某几个方法,却不知道其中的区别,看了官方文档今天来总结一下。
Interface Queue
实现它的类有:AbstractQueue, ArrayBlockingQueue, ArrayDeque, ConcurrentLinkedDeque, ConcurrentLinkedQueue, DelayQueue, LinkedBlockingDeque, LinkedBlockingQueue, LinkedList, LinkedTransferQueue, PriorityBlockingQueue, PriorityQueue, SynchronousQueue其中我们最熟悉的就是 LinkedList了。
在具体介绍方法之前,再从整体上了解一下Queue,除了基本的Collection操作以外,Queue还提供了额外的插入,提取和检查操作,这些方法都有两种形式:一种在操作失败时会抛出异常(异常什么的下次总结!),另一种返回特殊值(根据操作不同返回null或false),后一种形式的插入操作是专门给容量受限的队列实现来设计的,不过在大多数实现中,插入操作不会失败。
Throws Exception抛出异常 | Returns special value返回特殊值 | |
---|---|---|
Insert 插入 |
add(e) | offer(e) |
Remove 删除 |
remove() | poll() |
Examine 校验 |
element() | peek() |
队列通常(但不一定)以先进先出(FIFO)的方式对元素排序,例外是优先级队列,它根据提供的比较器对元素进行排列、或按自然顺序对元素进行排列,以及按后进先出(LIFO)排序(栈),无论用什么顺序,队列头部都是通过调用remove()或poll()删除元素,在FIFO队列中,新元素都是插入到队列尾部,其他类型的队列可能有不同的放置规则,每个队列实现都必须指定它的排序属性。
offer()方法在可能的情况下插入一个元素,否则返回false,这和Collection.add方法不同,后者只能通过抛出一个uncheck Exception来表示插入元素失败(什么是不检查异常?下次总结),offer()方法是为了正常情况下的“失败”而设计的,而不是异常情况,比如固定容量的队列。
remove()和poll()方法删除并且返回队首元素,至于从队列中删除哪一个元素就和队列排序策略的函数实现有关了(有各种实现),remove()和poll()的不同仅仅在于,当队列为空时他们的行为不同:remove()抛出异常,poll()返回null。
element()和peek()方法返回但不删除队首元素。
Queue接口没有定义阻塞队列的方法,这些方法在它的扩展接口BlockingQueue中有定义。
虽然有些实现(如LinkedList)也不禁止插入null值,但Queue的实现通常不允许插入null值。 尽管有些实现允许插入null值,但最好还是不要这么做,因为null值是作为poll()方法的特殊返回值的,他表示当前队列为空,如果插入null值就会引起混乱了。
Queue的实现中通常不定义基于元素版本的equals方法和hashCode方法,而是从Object类继承基于identity的版本,因为对于具有相同元素但顺序不同的队列,并不总是定义了基于元素的相等性。
-----------------------------------------分割线----------------------------------------------------------------------------------------------
现在我们对Queue和它的方法都有了一个概念上的认识和区分,接下来就进一步的来探索这些方法吧~
add(e) 方法
boolean add(E e)
在不违反容量限制的情况下将元素插入队列,插入成功返回true,如果没有可用空间则抛出IllegalstateException。
继承自:Collection的add()
参数:e-要插入的元素
返回: true
抛出:
IllegalStateException
- 由于容量限制插入失败
ClassCastException
- 由于指定元素的类禁止将其添加到队列中
NullPointerException
- 由于指定元素为null且队列不允许有null值
IllegalArgumentException
- 由于元素的某些属性禁止将其添加到队列中
Queue queue = new LinkedList();
System.out.println(((LinkedList) queue).add(1));
Queue queue2 = new ArrayDeque<>(2);
System.out.println(queue2.add(1));
/*
输出:
true
true
*/
(异常的情况下次补充吧~)
offer(E e)
boolean offer(E e)
在不违反容量限制的情况下将元素插入队列,对于使用容量限制的队列来说,offer方法比add方法更可取。
参数:e-要插入的元素
返回: 插入成功-true,失败-false
抛出:
ClassCastException
- 由于指定元素的类禁止将其添加到队列中
NullPointerException
- 由于指定元素为null且队列不允许有null值
IllegalArgumentException
- 由于元素的某些属性禁止将其添加到队列中
System.out.println(queue.offer(2));
System.out.println(queue2.offer(2));
/*
输出:
true
true
*/
remove()
E remove()
返回并删除队首元素,该方法和poll()方法的不同在于,当队列为空时它会抛出异常。
返回:队首元素
抛出:NoSuchElementException
- 队列为空
Queue queue = new LinkedList();
queue.offer(2);
System.out.println(queue.remove());
System.out.println(queue.remove());
输出:
2
Exception in thread "main" java.util.NoSuchElementException
poll()
E poll()
返回并删除队首元素,如果队列为空,则返回null。
返回:队首元素,队列为空返回null
Queue queue = new LinkedList();
queue.offer(2);
System.out.println(queue.poll());
System.out.println(queue.poll());
输出:
2
null
element()
E element()
返回但不删除队首元素,该方法和peek()方法的不同在于,当队列为空时它会抛出异常。
返回:队首元素
抛出:NoSuchElementException
- 队列为空
Queue queue = new LinkedList();
queue.offer(2);
System.out.println(queue.element());
queue.poll();
queue.element();
输出:
2
Exception in thread "main" java.util.NoSuchElementException
peek()
E peek()
返回但不删除队首元素,队列为空时返回null。
返回:队首元素,队列为空返回null
Queue queue = new LinkedList();
queue.offer(2);
System.out.println(queue.peek());
queue.poll();
System.out.println(queue.peek());
输出:
2
null