Java集合插入:设置与列表

时间:2011-05-18 11:52:04

标签: java list collections insert set

我正在考虑用大量独特的对象填充集合。 Set中的插入(比如HashSet)与List(比如ArrayList)的成本相比如何?

我的感觉是集合中的重复消除可能会导致轻微的开销。

7 个答案:

答案 0 :(得分:10)

没有“重复消除”,例如与所有现有元素进行比较。如果你插入哈希集,它实际上是哈希码的项目字典。除非已经存在具有相同哈希码的项目,否则没有重复检查。给定一个合理的(分布均匀的)哈希函数,它并没有那么糟糕。

正如Will所指出的,因为字典结构HashSet可能比ArrayList慢一点(除非你想在现有元素之间插入“)。它也有点大。我不确定这是一个显着的差异。

答案 1 :(得分:3)

你是对的:设置结构本质上更复杂,以便识别和消除重复。这种开销对您的案例是否重要应该使用基准测试。

另一个因素是内存使用情况。如果对象非常小,则set结构引入的内存开销可能很大。在最极端的情况下(TreeSet<Integer>ArrayList<Integer>),集合结构可能需要10倍以上的内存。

答案 2 :(得分:3)

如果您某些,您的数据将是唯一的,请使用列表。您可以使用设置强制此规则。

Sets are faster than Lists如果你有一个大数据集,而inverse is true用于较小的数据集。我没有亲自测试过这种说法。

哪种类型的列表?
另外,请考虑使用哪个List。 LinkedLists 可以更快地添加,删除元素。

ArrayLists 在随机访问(for循环等)方面更快,但这可以使用LinkedList的Iterator来解决。 ArrayLists在<{1}}更快更多

答案 3 :(得分:2)

如果目标是元素的唯一性,则应使用java.util.Set接口的实现。对于插入,删除和包含检查,类java.util.HashSetjava.util.LinkedHashSet具有O( alpha )(在最佳情况下接近O(1))复杂度。

ArrayList O( n )对象(不是索引)包含检查(您必须滚动整个列表)和插入(如果插入不在列表,你必须移动整个下划线数组。)

您可以使用保留插入顺序的LinkedHashSet并具有HashSet的相同潜力(仅占用更多内存)。

答案 4 :(得分:1)

您必须将具体实现(例如HashSetArrayList)进行比较,因为抽象接口Set / List并未真正告诉您有关性能的任何信息。

插入HashSet是一个相当便宜的操作,只要要插入的对象的hashCode()是理智的。它仍然会比ArrayList略慢,因为它的插入是一个简单的插入数组(假设您插入到最后并且仍有空闲空间;我不考虑调整内部数组的大小,因为它相同费用也适用于HashSet

答案 5 :(得分:1)

我认为你不能简单地根据建造收藏品的成本做出判断。您需要考虑的其他事项包括:

  • 输入数据集是否已订购?是否要求输出数据结构保留插入顺序?
  • 是否要求根据元素值对输出数据结构进行排序(或重新排序)?
  • 输出数据结构是否随后会被修改?怎么样?
  • 如果随后添加了其他元素,是否要求输出数据结构是免费的?
  • 您知道输入数据集中可能有多少元素吗?
  • 您可以测量输入数据集的大小吗? (或者它是通过迭代器提供的吗?)
  • 空间利用率是否重要?

这些都会影响您对数据结构的选择。

答案 6 :(得分:1)

Java列表:

如果您没有这样的要求,您必须保留或不重复。然后你可以使用List而不是Set。

List是Collection框架中的一个接口。其中扩展了Collection接口。和ArrayList,LinkedList是List接口的实现。

何时使用ArrayList或LinkedList

ArrayList:如果您有这样的要求,那么在您的应用程序中,大部分工作都是访问数据。然后你应该去ArrayList。因为ArrayList实现了标记接口的RtandomAccess接口。因为Marker接口ArrayList具有在O(1)时间内访问数据的能力。你可以在LinkedList上使用ArrayList来根据插入顺序获取数据。

LinkedList:如果您有这样的要求,您的主要工作是插入或删除。然后你应该在ArrayList上使用LinkedList。因为在LinkedList中插入和删除发生在O(1)时间,而在ArrayList中它发生在O(n)时间。

Java Set:

如果您的申请中有要求您不想要任何重复项。然后你应该去Set而不是List。因为Set不存储任何重复项。因为Set的工作原理是Hashing。如果我们在Set中添加对象,那么首先它检查桶中的对象的hashCode,如果它找到其中存在的任何hashCode,那么它就不会添加该对象。