为什么 Java 提供了几种不同的类型实现,Set
包括HashSet
和不?TreeSet
ArraySet
8 回答
仅基于无特定顺序的元素数组的集合总是有 O(n) 时间进行包含检查。IMO,它不会非常有用。您什么时候想使用它而不是HashSet
or TreeSet
?
数组最有用的方面是您可以非常快速地找到具有特定索引的元素。当涉及到集合时,这并不是很重要。
CopyOnWriteArraySet是一个由数组支持的集合。
这并不是特别有用,因为它的性能对于大型集合来说不是很好。
Android 有android.util.ArraySet(在 API 级别 23 中引入)和android.util.ArrayMap(在 API 级别 19 中引入)。
实际上 Set 的具体实现没有任何意义。任何集合都存储元素并保证它们的唯一性。我不能确定,但听起来你想要保留元素顺序的 Set 实现。如果我正确使用LinkedHashSet
.
Java 提供了多种Collection
接口实现,以实现最佳性能。ArrayList
在许多List
操作上表现良好。
对于Set
总是需要唯一性的操作,不同的实现提供了更好的性能。如果使用数组实现,则任何修改操作都必须遍历所有数组元素以检查它是否已在 Set 中。HashSet 和 TreeSet 大大简化了这个检查。
该Set
接口没有 get-by-index 方法,例如List.get(int)
,因此建议 Set 可以具有类似数组的属性是没有用的。
最终,所有“分组”类都在底层使用数组来存储它们的元素,但这并不意味着您必须公开访问数组的方法。
考虑indexed-tree-map,您将能够通过索引访问元素并获取元素的索引,同时保持排序顺序。可以将重复项作为同一键下的值放入数组中。
你总是可以自己实现它......现在可能只有一个非常非常有限的情况下它会有用(在这种情况下你可以使用更好的数据结构),那就是你有一个非常大的集合几乎永远不会改变,那么数组集将占用更少的内存(没有额外的指针),并且你会稍微更快地枚举整个集合......如果你保持数组排序,那么你仍然可以获得 O(lg n ) 搜索时间。
然而,这些差异纯粹是学术上的。在现实世界中,您永远不会真正想要这样的野兽