关于java:ArrayList或Linked List – 如果要执行插入/删除和查找操作,则使用哪个集合

ArrayList or Linked List - Which collection to use if both insertion/deletion and look up operation is to be performed

我们知道,Linked List用于快速插入删除
数组列表用于快速查找

我要求在List中保存10000条记录。 我会用哪个系列。
可以在该列表上执行查找和插入/删除操作。

我使用哪个系列,原因是什么?
要么
我会使用自己创建的收藏吗?


插入

LinkedList

先插入 - O(1)

最后插入 - O(1)

在任何地方插入 - O(n) - 这是因为需要通过索引找到要插入的位置。

ArrayList

先插入 - O(n)

最后插入 - O(1)

随处插入 - O(n)

所以LinkedListArrayList在任何地方都有相同的O(n)插入。

删除

LinkedList

首先删除 - O(1)

最后删除 - O(1)

删除任何地方 - O(n) - 再次,这是因为需要通过索引找到要删除的位置。

ArrayList

首先删除 - O(n)

最后删除 - O(1)

随处删除 - O(n)

所以LinkedListArrayList在任何地方都有相同的O(n)删除。

正如您所看到的,两者的插入和删除是相同的。
如果你总是插入最后一个操作,那么ArrayList适合使用,因为如果你知道索引,那么查找是O(1)和O(n)的LinkedList。我认为你需要找到更适合使用的黄金中间。

此外,如果你不关心无公开,你可以使用HashSet。它基于哈希表,并为插入和删除,查找提供合适的性能(O(1),O(许多情况下为log(n))。

HashSet jdoc

This class offers constant time performance for the basic operations (add, remove, contains and size), assuming the hash function disperses the elements >properly among the buckets.


每当您需要选择适合您的问题的数据结构时,请在以下链接中查看这些表格。
BIG-O Complextity


在不查看数据的情况下,除非您的用例涉及使用ListIterator进行大量插入和删除(=在不在任何一端操作时在LinkedList上获取O(1)插入和删除的方式),由于较低的开销和较少的指针解除引用,世界性能将支持ArrayList

您选择的重要因素:

  • 您的清单中有什么?如果您的列表是小对象的集合(例如,Integer),那么LinkedList的开销将更加明显。 LinkedList中的每个节点至少需要2个额外指针,估计每个节点的开销约为8个字节。更多内存意味着更多缓存未命中和更低性能。
  • 你将如何插入和删除?如果您只在列表的末尾插入和删除,那么ArrayList是可行的方法。如果您在随机位置插入和删除,那么ArrayList仍然可能是要走的路(因为扫描速度更快)。只有当您需要在开始时插入和/或一致地使用ListIterator时,您才能真正看到LinkedList带来的性能优势。
  • 您的列表有多无序,以及您需要多长时间执行完整扫描?虽然理论上所有内存访问都需要相同的时间,但是在RAM中迭代彼此相邻的元素(由于处理器缓存)比在整个地方跳转更快。
  • 最后 - 您是否考虑过使用SetMap来加速搜索和访问? O(n)列表访问快速总结,特别是如果您在循环内使用它。映射和集可以提供O(log n)O(1)访问(取决于实现),以显着提高性能。

    一些参考:

    • Java ArrayList与LinkedList的性能,仅与创建/插入和排序有关
    • 为什么处理排序数组比未排序数组慢? (c#但适用于Java)
    • https://github.com/joaquintides/usingstdcpp2015/blob/master/Mind%20the%20cache.pdf(c ++但列表vs适用于Java的矢量讨论 - 以LinkedList vs array的方式排序)