Stackoverflow翻译(1)-java-为什么LinkedList有add()、offer()和offerLast()这三个相同效果的方法?

Java集合框架:offer与add的区别及Deque接口的对称性探讨
这篇博客详细解释了Java中`offer`和`add`方法的区别,以及为何在`Deque`接口中引入`offerFirst`和`offerLast`。`offer`方法主要用于队列,可能因队列满等原因返回`false`,而`add`方法仅在元素已存在时返回`false`。`offerLast`的引入主要是为了保持接口的对称性,尽管在实际操作中它与`addLast`并无实质区别,都是将元素添加到双端队列的末尾。博客还讨论了`Deque`接口的实现如`LinkedList`,并指出这些方法的源码实现主要是为了接口的完整性和一致性。

我的理解

一、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 addLastpeek and peekFirstpoll and pollFirst, and remove and removeFirst.

 

写在最后:

这个系列是我在国内百度搜不到回答和解决方法的情况下,在Google找到回答和解决方法后,搬运回国的。不一定只有Stackoverflow的内容,也可能包含其他来源的答案;翻译也不一定是按原文翻译,是我基于对原文的理解给出的最简洁的解释。只要是国内百度解决不了而必须翻墙找的问题,我都会发在这个专栏。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值