【问题标题】:About implementation of ArrayDeque in Java关于Java中ArrayDeque的实现
【发布时间】:2015-10-01 05:46:37
【问题描述】:

文档说:

Deque 接口的 Resizable-array 实现。数组双端队列 没有容量限制;它们会根据需要增长以支持使用

但是我仍然想了解 ArrayDeque 的结构到底是什么,调整大小是如何工作的。如果有人能提供一个可靠的来源,我可以找到答案,那就太好了。根据我发现的一些谷歌结果,它可能实现为一个循环数组。这是真的吗?什么是增长政策?它类似于 ArrayList 吗?如果是,ArrayDeque在最后添加或删除元素等操作上是否有与ArrayList相似的性能?

谢谢。

【问题讨论】:

  • 阅读源码?
  • @chrylis 是的,我现在正在这样做。在我看来,它是一个圆形数组。并且在满时大小翻倍,这使得增长策略与 ArrayList 非常相似。我不明白为什么很多人说 ArrayDeque 比 ArrayList 快。
  • 谁说它更快?它们是不同类型的数据结构,而不是替代实现。
  • 为了在开始添加元素,ArrayDeque 会更快,因为如果它不需要调整大小,它只会减少头部计数器(可能会环绕)。 ArrayList 会将所有元素复制到 n+1。但适合在最后添加,它们应该非常相似。

标签: java arraylist arraydeque


【解决方案1】:

ArrayListArrayDeque 的增长策略未记录在案,并且可能因 JDK 实现甚至 JDK 版本而异。例如,在Open JDK 6 中是(n*3/2+1),但在Open JDK 8 中是(n*3/2)。同样在 JDK 6 ArrayList 中,默认构造函数最初是用 10 个元素数组创建的,而在 JDK 8 中,它仅在添加至少一个元素时才分配一个数组。

ArrayDeque 实现的更改频率低于ArrayList。默认情况下,它始终在内部使用以16 开头的二次幂大小的数组,并在必要时将其加倍,因此ArrayListArrayDeque 的内存占用可能不同(对于ArrayDeque,您的平均内存占用会更少重新分配,但更浪费内存)。

除非需要重新分配,否则 ArrayListArrayDeque 添加到尾部的速度大致相同。重新分配事件可能发生在不同的点。例如,默认情况下,ArrayList 的第一次重新分配将在添加元素 #11 时发生,但对于 ArrayDeque,它将发生在元素 #16 上。

ArrayDeque 的优点是能够像在尾部一样快地向头部添加/删除元素。相反,ArrayList 将在O(n) 时间内完成,因为它必须移动所有现有元素。因此,当您需要添加/删除头部和尾部时,请使用ArrayDeque。如果只需要修改尾部,通常首选ArrayList

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-17
    • 2012-10-25
    • 2023-04-01
    • 1970-01-01
    • 2023-03-19
    • 2013-05-04
    • 1970-01-01
    • 2015-07-11
    相关资源
    最近更新 更多