【问题标题】:Why does the class ArrayDeque not extend from AbstractQueue?为什么类 ArrayDeque 不从 AbstractQueue 扩展?
【发布时间】:2014-09-29 04:12:25
【问题描述】:

为什么类ArrayDeque定义为

public class ArrayDeque<E> extends AbstractCollection<E>
                       implements Deque<E>, Cloneable, Serializable

而不是像

public class ArrayDeque<E> extends AbstractQueue<E>
                       implements Deque<E>, Cloneable, Serializable

如果您看下图(其中有错误,ArrayDeque 与 Set 的关系完全错误),ArrayDeque 将从 AbstractQueue 继承是有道理的,因为它通过 Deque 接口间接实现了 Queue 接口。


(来源:academic.ru)

【问题讨论】:

  • 你为什么想知道?你的问题是合法的,但这是一个内部决定,你不应该真正关心:)
  • 查看ArrayDeque、AbstractQueue 和AbstractCollection 的源代码并尝试找出这个谜团的答案?
  • 我猜这是因为 ArrayDeque 早于 AbstractQueue,但事实并非如此。 ArrayDeque 来自 Java 6,而 AbstractQueue 来自 Java 5。

标签: java collections arraydeque


【解决方案1】:

其中一位 jsr166 维护者发布在OpenJDK core-libs:

我根本不认为 ArrayDeque 是一个队列/双端队列。我们只有两个 这里的基本数据结构(ArrayList(普通可调整大小的数组)和 ArrayDeque(可调整大小的圆形数组))都可以实现 List 和 以合理的方式排队,ArrayDeque 可以额外实现 Deque。

扩展 AbstractCollection 并实现 Deque 与该观点一致。

这也是一个保守的举动,因为it would allow future versions of ArrayDeque to extend AbstractList 实现了大部分 List 接口。仅当它被认为是合法的和或desirable to implement both List and Queue 由于冲突的equals/hashCode 合同时才会发生这种情况。

【讨论】:

    【解决方案2】:

    ArrayDeque 可以用作双端队列、堆栈和链表。我认为这更像是一个设计决定。在这里,在 ArrayDeque 中,我们在添加/删除元素时需要更加具体。例如。

    [ArrayDeque.java]
        public boolean add(E e) {
            addLast(e);
            return true;
        }
    [AbstractQueue.java]
    public boolean add(E e) {
            if (offer(e))
                return true;
            else
                throw new IllegalStateException("Queue full");
        }
    

    由于双端队列是双端的,我们需要明确添加元素的位置。

    另一个设计考虑可能是减少调用堆栈。如果继承 AbstractQueue,它会增加函数调用堆栈而没有额外的好处。

    例如,

    现在,

    add() -> addLast()

    如果继承AbstractQueue,

    add() -> offer() -> offerLast() -> addLast()

    此外,通过不继承 AbstractQueue,我们能够重用在 ArrayDeque 中实现的不同数据结构(队列、堆栈和链表)的小块添加、删除操作。

    最后,Joshua Bloch(此 API 的作者)知道得更清楚:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-09
      • 2018-07-21
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-04
      相关资源
      最近更新 更多