我正在实现一种算法,该算法将在集合的末尾添加字符串并在开头删除字符串。在极少数情况下,我会执行随机访问删除以在最后推送它。我主要是一个C ++开发人员,而且我不确定在java的关键循环中使用什么是好的。我不认为java列表非常适合这项任务。当然它会起作用,但我已经在努力解决性能问题。
链表?向量?建议?
答案 0 :(得分:3)
我建议使用ArrayDeque
,它实现Queue
和Deque
接口,但不实现List
(您可能不需要):
Deque
接口的可调整大小的数组实现。阵列deques 没有容量限制;他们成长为必要的支持 用法。它们不是线程安全的;在没有外部的情况下 同步,它们不支持多个并发访问 线程。禁止使用空元素。这堂课很可能是 用作堆栈时比Stack
更快,并且比LinkedList
更快 当用作队列时。
您还提到了删除:
此界面提供了两种删除内部元素的方法,
removeFirstOccurrence
和removeLastOccurrence
。
ArrayDeque
提供了您需要的所有方法 - addFirst(E e)
,addLast(E e)
,removeFirst()
。
另请参阅this question以了解有关ArrayDeque
的更多信息。
P.S。以上是来自上方链接的some collections benchmark,其他人提及ArrayDeque
,LinkedList
和ArrayList
;)
答案 1 :(得分:1)
您似乎正在尝试实施队列(LIFO)。 http://docs.oracle.com/javase/6/docs/api/java/util/Queue.html。您可以查看源代码及其实现方式,以获得更多想法。
答案 2 :(得分:1)
听起来你想要一个队列,是吗?查看Queue
界面。
Queue<String> strQueue = new LinkedList<String>();
strQueue.offer("Hello");
strQueue.offer("World");
System.out.println(strQueue.poll());
System.out.println(strQueue.poll());
打印:
Hello
World
答案 3 :(得分:1)
在ArrayList上使用Vector是没有意义的,除非你需要所有单独的操作synchronized
,这通常不会。{/ p>
如果你只是进行头尾插入/删除,那么LinkedList最有意义。但是,如果列表很大并且您需要进行随机访问检索,那么必须遍历列表可能会非常痛苦。
另一方面,ArrayList提供了非常便宜的随机访问,但是从列表头部插入或删除元素需要移动其余的后备阵列。 JDK实现通过调用System.arraycopy()
来实现这一点,List
能够非常便宜地完成。
在这种情况下,最好的想法是使用两种实现进行基准测试并比较结果。编写有问题的算法只需使用List
,您就可以轻松地在不同的{{1}}实现中交换基准。
我没有看到在ArrayList上使用常规数组的目的是什么,因为你必须自己编写头/尾删除/插入代码,并在大小超过容量时处理数组大小调整,所有ArrayList已经为你做了。
答案 4 :(得分:1)
java.util.ArrayDeque
支持使用循环缓冲区进行队列操作,这可能是最有效的方法,最后添加并在开头删除,但它不支持索引的随机访问 - 你不能删除索引 n 中的条目,而不是遍历迭代器。有一些方法可以删除特定值的第一个/最后一个匹配项,但这些方法在内部进行线性搜索。
答案 5 :(得分:1)
不确定java列表的含义。您描述的问题听起来像是LinkedList的经典案例。 documentation指定“所有操作都可以按预期的方式执行双向链接”。这意味着在O(1)中完成在末尾插入对象以及从头开始删除对象,这意味着无论您在列表中有多少元素,它都需要相同的时间。然而,随机访问更加困难,应该在O(N)中完成,这意味着时间与列表中实际的元素数量成正比。
当然,根据您拥有的元素数量,带有O(1)的链表可能不会给出最佳时间。例如,如果您只期望列表中的一些元素,那么可能具有O(N)添加/删除时间但更快访问者的数据结构可能实际上表现更好。但对于较大的结构,LinkedList类可能就是起点。