【发布时间】:2014-11-21 23:41:49
【问题描述】:
我想在我的程序中使用 ArrayBuffer 来保存数字列表。我想用它作为队列。每次删除列表中的第一项并使用它。然后我想知道每次我删除第一个项目时,队列中的所有其他数字都会移动一个位置。我的意思是下次我可以再次阅读 item(0) 吗?
【问题讨论】:
标签: java scala arraybuffer
我想在我的程序中使用 ArrayBuffer 来保存数字列表。我想用它作为队列。每次删除列表中的第一项并使用它。然后我想知道每次我删除第一个项目时,队列中的所有其他数字都会移动一个位置。我的意思是下次我可以再次阅读 item(0) 吗?
【问题讨论】:
标签: java scala arraybuffer
如果您想使用数组支持的数据结构(例如,出于运行时(缓存局部性)或存储(无下一个指针)效率的原因),您可能需要考虑java.util.ArrayDeque。这个类有效地实现了一个循环数组,当它满时调整大小。 poll()(检索并删除第一个元素)方法通过简单地增加起始偏移量来实现
缺点是,即使这个类实现了java.util.Queue接口,也没有隐式转换为scala.collection.mutable.Queue,所以不能使用map等Scala集合方法。
注意:从 2.11 开始,Scala 没有 Deque 接口,更不用说 ArrayDeque 实现了。
【讨论】:
ArrayBuffer 基本上是一个数组,它实现了Buffer 的所有便捷方法。
它按照您描述的方式工作:如果您删除一个元素,则所有剩余元素都将转移以“填补空白”,并且如文档中所述,可能需要一些时间,特别是如果您删除第一个元素:
追加、更新和随机访问需要固定时间(摊销时间)。前置和删除在缓冲区大小中是线性的。
因此我不建议使用 ArrayBuffer 作为队列。
实际上,最好的选择是您的问题:只需使用Queue。它被设计成,嗯……一个队列!
【讨论】:
为什么不用队列作为队列?Java Queue
它有一个叫做 poll() 的好方法(检索并删除此队列的头部,如果此队列为空,则返回 null。)
这不是您需要的吗?它的性能也比您的 Array 解决方案更好。
【讨论】:
如果您查看 Scala source code 或 ArrayBuffer,您将看到 remove 的以下实现:
/** Removes the element on a given index position. It takes time linear in
* the buffer size.
*
* @param n the index which refers to the first element to delete.
* @param count the number of elements to delete
* @throws Predef.IndexOutOfBoundsException if `n` is out of bounds.
*/
override def remove(n: Int, count: Int) {
require(count >= 0, "removing negative number of elements")
if (n < 0 || n > size0 - count) throw new IndexOutOfBoundsException(n.toString)
copy(n + count, n, size0 - (n + count))
reduceToSize(size0 - count)
}
因此,删除的元素将不再存在于数组中,但实际上,删除意味着复制所有元素(在您的定义中为“移位”),并且对于较长的数组来说会很慢。
【讨论】: