在这种情况下我应该使用什么样的收藏品?

时间:2017-01-10 20:14:39

标签: java list loops collections set

在这个用例中,我需要在集合x中存储一组项目。如果项目已存在(无重复项),我不想将项目插入x。我也不在乎插入订单。大小x变化很大(在<10项或非达到数万项时可能非常小)。

虽然没有重复项且没有订单指向使用Set,但我需要在构建x并使用它们执行操作后有效且快速地遍历所有项目(但没有改变他们)。 Set仍然是最佳选择吗?

我希望任何方向 - 检查List是否包含每个插入前的元素(以避免重复)或迭代Set成员是否更为昂贵?关于最佳实践/效率和成本的任何建议都将非常感谢,谢谢。

5 个答案:

答案 0 :(得分:1)

检查List是否已包含该元素的成本要高得多。

迭代Set比迭代List慢一点,但不是很大,只是通过一个常数因子,而检查List中元素的包含每个元素花费线性时间并使整个事物成为二次方。

答案 1 :(得分:1)

如果你需要能够快速检查一个项目是否已经存在,那么HashSet肯定是最好的选择,因为它在内部使用HashMap,因此每个查找都是O(1)。 虽然此查找的列表非常昂贵,但它会逐个检查所有元素。

当你需要迭代所有元素时,使用List和Set没有区别。

值得注意的是HashSet将使用更多内存,但成千上万的内存不应该造成问题。

因此,HashSet是您案件的明显赢家。

答案 2 :(得分:1)

我建议使用LinkedHashSet,因为它的添加和删除操作在O(1)中运行(假设均匀分配哈希码)。添加/删除元素的效率可能低于HashSet,但如果在添加大量元素后删除了许多元素,它应具有更好的迭代性能。

在这种情况下,通常需要O(n)进行查找。

答案 3 :(得分:0)

我建议将数据插入到地图中以避免重复项目,然后将地图转换为List。

如果您使用的是Java 8,则可以执行类似的操作

    List<Object> result = map.entrySet().stream()
            .map(x -> x.getKey())
            .collect(Collectors.toList());

答案 4 :(得分:-1)

在构造x之后使用set来构造x你可以简单地将内容复制到数组或任何其他类型,以便以空间复杂性为代价来提高时间复杂度。