简体   繁体   English

Java集合维护插入顺序

[英]Java collections maintaining insertion order

Why do some collection data structures not maintain the order of insertion? 为什么某些集合数据结构不能保持插入顺序? What is the special thing achieved compared to maintaining order of insertion? 与维持插入顺序相比,实现的特殊功能是什么? Do we gain something if we don't maintain the order? 如果我们不维持订单,我们会获得一些收益吗?

Performance. 性能。 If you want the original insertion order there are the LinkedXXX classes, which maintain an additional linked list in insertion order. 如果您需要原始广告订单,则会有LinkedXXX类,它们会按插入顺序维护其他链接列表。 Most of the time you don't care, so you use a HashXXX, or you want a natural order, so you use TreeXXX. 大多数时候你不在乎,所以你使用HashXXX,或者你想要一个自然的顺序,所以你使用TreeXXX。 In either of those cases why should you pay the extra cost of the linked list? 在任何一种情况下,您为什么要支付链表的额外费用?

The collections don't maintain order of insertion. 集合不保持插入顺序。 Some just default to add a new value at the end. 有些只是默认在最后添加一个新值。 Maintaining order of insertion is only useful if you prioritize the objects by it or use it to sort objects in some way. 维护插入顺序仅在通过它对对象进行优先级排序或使用它以某种方式对对象进行排序时才有用。

As for why some collections maintain it by default and others don't, this is mostly caused by the implementation and only sometimes part of the collections definition. 至于为什么有些集合默认维护它而其他集合没有,这主要是由实现引起的,有时只是集合定义的一部分。

  • Lists maintain insertion order as just adding a new entry at the end or the beginning is the fastest implementation of the add(Object ) method. 列表维护插入顺序,因为只是在结尾处添加新条目,或者开头是add(Object)方法的最快实现。

  • Sets The HashSet and TreeSet implementations don't maintain insertion order as the objects are sorted for fast lookup and maintaining insertion order would require additional memory. 设置 HashSet和TreeSet实现不维护插入顺序,因为对象的排序是为了快速查找,维护插入顺序需要额外的内存。 This results in a performance gain since insertion order is almost never interesting for Sets. 这导致性能增益,因为插入顺序几乎从不对集合感兴趣。

  • ArrayDeque a deque can used for simple que and stack so you want to have ''first in first out'' or ''first in last out'' behaviour, both require that the ArrayDeque maintains insertion order. ArrayDeque deque可用于简单的que和stack,因此你想要“先进先出”或“先进去”行为,这两者都要求ArrayDeque保持插入顺序。 In this case the insertion order is maintained as a central part of the classes contract. 在这种情况下,插入顺序将作为类合同的中心部分进行维护。

  • The insertion order is inherently not maintained in hash tables - that's just how they work (read the linked-to article to understand the details). 插入顺序本身不在哈希表中维护 - 这就是它们的工作方式(阅读链接到文章以了解详细信息)。 It's possible to add logic to maintain the insertion order (as in the LinkedHashMap ), but that takes more code, and at runtime more memory and more time. 可以添加逻辑来维护插入顺序(如在LinkedHashMap ),但这会占用更多代码,并且在运行时会有更多内存和更多时间。 The performance loss is usually not significant, but it can be. 性能损失通常不大,但可以。
  • For TreeSet/Map , the main reason to use them is the natural iteration order and other functionality added in the SortedSet/Map interface. 对于TreeSet/Map ,使用它们的主要原因是自然迭代顺序和SortedSet/Map界面中添加的其他功能。

Depends on what you need the implementation to do well. 取决于您需要实施哪些方面做得好。 Insertion order usually is not interesting so there is no need to maintain it so you can rearrange to get better performance. 插入顺序通常不是很有趣,因此无需维护它,因此您可以重新排列以获得更好的性能。

For Maps it is usually HashMap and TreeMap that is used. 对于Maps,通常使用HashMap和TreeMap。 By using hash codes, the entries can be put in small groups easy to search in. The TreeMap maintains a sorted order of the inserted entries at the cost of slower search, but easier to sort than a HashMap. 通过使用哈希码,可以将条目放在易于搜索的小组中.TreeMap以较慢的搜索为代价维护插入条目的排序顺序,但比HashMap更容易排序。

When you use a HashSet (or a HashMap) data are stored in "buckets" based on the hash of your object. 当您使用HashSet(或HashMap)时,数据会根据您对象的哈希值存储在“桶”中。 This way your data is easier to access because you don't have to look for this particular data in the whole Set, you just have to look in the right bucket. 这样您的数据就更容易访问,因为您不必在整个Set中查找此特定数据,只需查看正确的存储桶即可。

This way you can increase performances on specific points. 这样您就可以提高特定点的表现。

Each Collection implementation have its particularity to make it better to use in a certain condition. 每个Collection实现都有其特殊性,可以更好地在特定条件下使用。 Each of those particularities have a cost. 每个特殊性都有成本。 So if you don't really need it (for example the insertion order) you better use an implementation which doesn't offer it and fits better to your requirements. 因此,如果您真的不需要它(例如插入顺序),您最好使用不提供它的实现,并更好地满足您的要求。

由于某些Collection不维护订单,因此会计算内容的hashCode并将其相应地存储在相应的存储桶中。

Why is it necessary to maintain the order of insertion? 为什么有必要维持插入顺序? If you use HashMap , you can get the entry by key . 如果使用HashMap ,则可以key获取条目。 It does not mean it does not provide classes that do what you want. 这并不意味着它不提供满足您需求的类。

Theres's a section in the O'Reilly Java Cookbook called "Avoiding the urge to sort" The question you should be asking is actually the opposite of your original question ... "Do we gain something by sorting?" Theres是O'Reilly Java Cookbook中的一个部分,名为“避免排序的冲动”。你应该问的问题实际上与你原来的问题相反......“我们通过排序获得了什么?” It take a lot of effort to sort and maintain that order. 排序和维护该订单需要花费很多精力。 Sure sorting is easy but it usually doesn't scale in most programs. 确定排序很容易,但在大多数程序中通常无法扩展。 If you're going to be handling thousands or tens of thousands of requests (insrt,del,get,etc) per second whether not you're using a sorted or non sorted data structure is seriously going to matter. 如果你要每秒处理成千上万或数万个请求(insrt,del,get等),那么你是否正在使用已排序或非排序的数据结构是非常重要的。

I can't cite a reference, but by design the List and Set implementations of the Collection interface are basically extendable Array s. 我不能引用引用,但是通过设计, Collection接口的ListSet实现基本上是可扩展的Array As Collections by default offer methods to dynamically add and remove elements at any point -- which Array s don't -- insertion order might not be preserved. 由于Collections默认情况下提供了在任何点动态添加删除元素的方法 - Array不这样做 - 可能不会保留插入顺序。 Thus, as there are more methods for content manipulation, there is a need for special implementations that do preserve order. 因此,由于存在更多用于内容操纵的方法,因此需要保持顺序的特殊实现。

Another point is performance, as the most well performing Collection might not be that, which preserves its insertion order. 另一点是性能,因为性能最佳的Collection可能不是那个,它保留了它的插入顺序。 I'm however not sure, how exactly Collections manage their content for performance increases. 然而,我不确定Collections如何管理其内容以提高性能。

So, in short, the two major reasons I can think of why there are order-preserving Collection implementations are: 因此,简而言之,我可以想到为什么存在保持订单的Collection实现的两个主要原因是:

  1. Class architecture 类架构
  2. Performance 性能

Okay ... so these posts are old as compared to now, but insertion order is needed depending on your need or application requirements, so just use the right type of collection. 好的...所以这些帖子与现在相比较旧,但根据您的需要或应用程序要求需要插入顺序,所以只需使用正确的集合类型即可。 For most part, it is not needed, but in a situation where you need to utilize objects in the order they were stored, I see a definite need. 在大多数情况下,它不是必需的,但在需要按照存储顺序使用对象的情况下,我看到了一定的需求。 I think order matters when you are creating for instance a wizard or a flow engine or something of that nature where you need to go from state to state or something. 我认为当您创建例如向导或流引擎或某种性质的东西时,顺序很重要,您需要从一个州到另一个州。 In that sense you can read off stuff from the list without having it keep track of what you need next or traverse a list to find what you want. 从这个意义上讲,您可以从列表中读取内容,而无需跟踪下一步所需内容或遍历列表以查找所需内容。 It does help with performance in that sense. 从这个意义上讲,它确实有助于提升性能 It does matter or else these collections would not make much sense. 它确实很重要,否则这些收藏品就没有多大意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM