我的理解
一、add和offer的不同在于,返回false的原因有无限制。
add 当且仅当该元素已经存在时返回false
offer 可出于任何原因返回false,例如 队列已满
其他是一样的。
二、为什么要加offerLast:
从offerLast的用法和效果来说,完全是和offer一样的。增加它的目的,是在Java 6增加了Deque接口后,为了实现双端队列,需要增加-first 和 -last变体,也就要增加offerFirst和offerLast。(Deque继承Queue,而Queue是单端队列,先进后出,所以只有offer()和add()方法)为了用冗余换对称性——例如add/addFirst/addLast,如果offer有offer和offerFirst,却没有offerLast,就没有“编程之美”了——所以还是增加了一个offerLast()。
而Deque接口有三种实现方式,分别是LinkedList、ArrayDeque、LinkedBlockingDeque,其中LinkedList是最常用的。
三、源码解析
因此,事实上,如果我们从源码去看的话。就以用LinkedList实现的Deque举例,可以发现
/**
* Appends the specified element to the end of this list.
*
* <p>This method is equivalent to {@link #add}.
*
* @param e the element to add
*/
public void addLast(E e) {
linkLast(e);
}
/**
* Appends the specified element to the end of this list.
*
* <p>This method is equivalent to {@link #addLast}.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
linkLast(e);
return true;
}
/**
* Adds the specified element as the tail (last element) of this list.
*
* @param e the element to add
* @return {@code true} (as specified by {@link Queue#offer})
* @since 1.5
*/
public boolean offer(E e) {
return add(e);
}
/**
* Inserts the specified element at the end of this list.
*
* @param e the element to insert
* @return {@code true} (as specified by {@link Deque#offerLast})
* @since 1.6
*/
public boolean offerLast(E e) {
addLast(e);
return true;
}
可以清楚地从Java源码中的注释看到,offer方法其实是用于实现Deque接口的额外方式,而它仅仅是简单调用add里的对应方法而已:offer = add, offerLast = addLast + return true。而add其实都是对应linkLast()方法,addLast = linkLast, add = linkLast + return true。所以offer和offerLast是完全相同的方法!仅仅是为了实现对称性。(看到这里,突然觉得《编程之美》还是有必要拜读一下。)
原文:
The Queue interface was added in Java 5. It defined the offer
method, which adds an element at the end.
(The offer
method and the add
method both return booleans. They differ in that add
is permitted to reject the element and return false only if the element is already present in the collection. The offer
method can reject the element for other reasons, such as the queue being full.)
With Queue.offer
, there is little question about the semantics, as elements are generally added to the tail of a queue and removed from the head.
The Deque interface was added in Java 6. A deque allows elements to be added to and removed from both the head and tail, so Deque
defines offerFirst
and offerLast
methods. A deque is also a queue, so Deque
is a sub-interface of Queue
. Thus it inherits the offer
method from Queue
. That's how Deque
ends up with both offer
and offerLast
.
We probably could have gotten by without adding offerLast
, but that would have left asymmetries in the Deque
interface. Many operations work on both the head and the tail (add, get, offer, peek, poll, remove) so it makes sense for all of them to have -first and -last variants, even though this adds redundancy. This redundancy occurs with other Queue
methods as well, such as add
and addLast
, peek
and peekFirst
, poll
and pollFirst
, and remove
and removeFirst
.
写在最后:
这个系列是我在国内百度搜不到回答和解决方法的情况下,在Google找到回答和解决方法后,搬运回国的。不一定只有Stackoverflow的内容,也可能包含其他来源的答案;翻译也不一定是按原文翻译,是我基于对原文的理解给出的最简洁的解释。只要是国内百度解决不了而必须翻墙找的问题,我都会发在这个专栏。