我对我在Java程序中使用的数据结构有特定的要求。它(数据结构)应该能够容纳大量数据(不固定),我的主要操作是在最后添加,并从头开始删除/读取(LinkedLists看起来很好)。但偶尔,我也需要从中间删除,这就是LinkedLists太痛苦了。任何人都可以建议我解决这个问题吗?或者我可以通过哪些优化使LinkedLists中的删除更少痛苦?
感谢您的帮助!
答案 0 :(得分:4)
LinkedHashMap可能适合您的目的 你可以使用迭代器从前面提取东西 当您需要访问列表中间时,按键查找条目
答案 1 :(得分:3)
LinkedList
落在随机访问上。没有随机访问查找的删除是固定时间,对于长列表来说真的不是太糟糕。
ArrayList
通常很快。从中间插入和删除的速度比您预期的要快,因为块内存移动速度非常快。在开始附近移除和插入,以使所有以下数据向下或向上移动。
ArrayDeque
与ArrayList
类似,只是它使用循环缓冲区并且具有奇怪的界面。
通常的建议:尝试一下。
答案 2 :(得分:2)
你可以尝试在evey 10000th元素之后使用带有指针的链表,这样你就可以减少找到你想要删除的中间的时间。 以下是链表的一些不同变体: http://experimentgarden.blogspot.com/2009/08/performance-analysis-of-thirty-eight.html
答案 3 :(得分:0)
LinkedHashMap可能是要走的路。非常适合迭代,双端运算和寻求中间。但是,内存中的额外成本,因为您需要在基本集合之上管理一组键。另外我认为它会在你删除的空格中留下“空白”,导致一组非连续的键(不应该影响迭代)。
编辑:啊哈!我知道你需要什么:LinkedMultiSet! LinkedHashMap的所有好处,但没有多余的密钥集。但是,它使用起来有点复杂。
答案 4 :(得分:0)
首先,您需要考虑是否将从列表中心删除经常与列表长度相比较。如果您的列表包含N
项,但删除的频率低于1/N
,请不要担心。根据您的喜好使用LinkedList
或ArrayDeque
。 (如果你的列表偶尔很大然后缩小,但大多数都很小,LinkedList
更好,因为它很容易恢复内存;否则,ArrayDeque
不需要额外的对象,所以它更快一点更紧凑 - 除了底层数组永远不会收缩。)
另一方面,如果你删除的频率比1/N
高得多,那么你应该考虑一个LinkedHashSet
,它在一个哈希集之上维护一个链表列表 - 但是它是一套,所以请记住,你不能存储重复的元素。这会将LinkedList
和ArrayDeque
的开销放在一起,但如果您经常进行中心删除,则可能是值得的。
然而,最佳结构 - 如果你真的需要每一个最后一盎司的速度并且愿意花费编码时间来获得它 - 将是一个“可调整大小”的数组(即当它太小时重新分配)循环缓冲区,您可以通过将元素设置为null来清除中间的元素。 (如果你有一个反常的用例,你也可以在太多空时重新分配缓冲区。)我不建议编码这个,除非你真的喜欢编码高性能数据结构或有充分的证据证明这是其中一个代码中的关键瓶颈,因此您确实需要它。