Java集合维护插入顺序
为什么一些集合数据结构不能保持插入顺序? 与维持插入顺序相比,所取得的特殊成就是什么? 如果我们不维持秩序,我们会得到什么?
性能。 如果您想要原始广告订单,则会有LinkedXXX类,它们按照广告订单维护额外的链接列表。 大部分时间你不关心,所以你使用HashXXX,或者你想要一个自然的顺序,所以你使用TreeXXX。 在这两种情况下,为什么要支付链表的额外费用?
集合不保持插入的顺序。 有些只是默认添加一个新的值在最后。 维护插入的顺序只有在按照优先顺序排列对象或者以某种方式对对象进行sorting时才有用。
至于为什么有些集合默认维护它,其他集合则不是这样,这主要是由实现导致的,有时只是集合定义的一部分。
-
列表维护插入顺序,只是在最后添加一个新条目,或者开始是add(Object)方法的最快实现。
-
集 HashSet和TreeSet实现不维护插入顺序,因为对象被快速查找sorting,并且维护插入顺序将需要额外的内存。 这导致性能增益,因为插入顺序对于集合来说几乎是不感兴趣的。
-
ArrayDeque deque可以用于简单的que和stack,所以你想要“先进先出”或者“先进后出”的行为,都要求ArrayDeque维护插入顺序。 在这种情况下,插入订单被保持为类合同的中心部分。
- 插入顺序本来就不在哈希表中维护 – 这是他们如何工作(阅读链接到的文章,了解细节)。 可以添加逻辑来维护插入顺序(如在
LinkedHashMap
),但需要更多代码,并且在运行时需要更多的内存和更多的时间。 性能损失通常不显着,但可以。 - 对于
TreeSet/Map
,使用它们的主要原因是在SortedSet/Map
接口中添加的自然迭代顺序和其他function。
取决于你需要什么执行才能做好。 插入顺序通常不是很有意思,所以不需要维护,所以可以重新排列以获得更好的性能。
对于地图,通常是使用HashMap和TreeMap。 通过使用散列码,条目可以放在一个容易search的小组中.ShitMap以较慢的search为代价维护插入条目的sorting顺序,但是比HashMap更容易sorting。
当你使用一个HashSet(或一个HashMap)数据存储在“桶”基于你的对象的散列。 这样你的数据更容易访问,因为你不必在整个集合中查找这个特定的数据,你只需要在正确的桶中查找。
这样可以提高特定点的performance。
每个集合实现都有其特殊性,以便在特定条件下使用更好。 每一个特点都有成本。 因此,如果您不需要它(例如插入顺序),则最好使用不提供它的实现,并且更符合您的要求。
为什么需要维护插入的顺序? 如果您使用HashMap
,您可以通过key
获取input。 这并不意味着它不提供你想要的东西。
Theres在O'Reilly的Java Cookbook中的一段名为“避免sorting的冲动”你应该问的问题实际上与你原来的问题相反……“我们通过sorting获得了什么? 分类和维护这个订单需要花费很多的精力。 确定sorting很容易,但通常在大多数程序中不能缩放。 如果你要每秒处理数千或数万的请求(insrt,del,get等),不pipe你使用的是sorting还是非sorting的数据结构,都是非常重要的。
一些Collection由于不维护顺序,他们计算内容的hashCode并将其存储在相应的bucket中。
我无法引用参考,但通过devise, Collection
接口的List
和Set
实现基本上是可扩展的Array
。 由于默认情况下提供的方法dynamic地添加和删除任何点上的元素 – 哪些Array
没有 – 插入顺序可能不会保留。 因此,由于内容操作有更多的方法,因此需要特殊的实现来保持顺序。
还有一点是性能,因为performance最好的Collection
可能不是那个,它保留了它的插入顺序。 但我不确定, Collections
如何pipe理其内容以提高性能。
所以,总之,我能想到为什么有顺序保存的Collection
实现的两个主要原因是:
- 类架构
- 性能
好吧…所以这些post与现在相比是旧的,但根据您的需要或应用程序的要求,插入顺序是需要的,所以只需使用正确的收集types。 大多数情况下,这是不必要的,但是在需要按照存储顺序使用对象的情况下,我看到了一个确定的需求。 我认为当你创build一个向导或stream引擎的实例时,或者你需要从一个状态到另一个状态的事物,这个顺序很重要。 从这个意义上说,你可以从列表中读取东西,而不需要跟踪你下一步需要的东西,或者遍历列表来find你想要的东西。 它在这个意义上确实有助于performance。 这确实很重要,否则这些collections就没有多大意义。