哪个集合用于前面的关键删除和最后添加?

时间:2012-08-30 17:46:36

标签: java

我正在实现一种算法,该算法将在集合的末尾添加字符串并在开头删除字符串。在极少数情况下,我会执行随机访问删除以在最后推送它。我主要是一个C ++开发人员,而且我不确定在java的关键循环中使用什么是好的。我不认为java列表非常适合这项任务。当然它会起作用,但我已经在努力解决性能问题。

链表?向量?建议?

6 个答案:

答案 0 :(得分:3)

我建议使用ArrayDeque,它实现QueueDeque接口,但不实现List(您可能不需要):

  

Deque接口的可调整大小的数组实现。阵列deques   没有容量限制;他们成长为必要的支持   用法。它们不是线程安全的;在没有外部的情况下   同步,它们不支持多个并发访问   线程。禁止使用空元素。这堂课很可能是   用作堆栈时比Stack更快,并且比LinkedList更快   当用作队列时。

您还提到了删除:

  

此界面提供了两种删除内部元素的方法,   removeFirstOccurrenceremoveLastOccurrence

ArrayDeque提供了您需要的所有方法 - addFirst(E e)addLast(E e)removeFirst()

另请参阅this question以了解有关ArrayDeque的更多信息。

P.S。以上是来自上方链接的some collections benchmark,其他人提及ArrayDequeLinkedListArrayList;)

答案 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类可能就是起点。