java 为什么我们在HashSet中没有得到有序的序列

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16874914/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 00:13:56  来源:igfitidea点击:

Why do we not get the ordered sequence in HashSet

javahashset

提问by Make

I am using the HashSetfor adding the elements and retrieving them, I know that I will not retrieve the data in sequence in which I added them, but I want to know the exact reason why Is it happeing?

我正在使用HashSet来添加元素并检索它们,我知道我不会按添加它们的顺序检索数据,但我想知道它发生的确切原因?

import java.util.HashSet;
import java.util.Iterator;

 public class HS {
     public static void main(String args[]) {
         HashSet h=new HashSet();
         h.add("Mayank");
         h.add("Mayank");

         h.add("Vashist");
         h.add("Dinesh");

         h.add("Vashist");

         Iterator itr=h.iterator();
         while(itr.hasNext()) {
             System.out.println(itr.next());
         }
     }
 }

回答by Boris the Spider

This is just the contract for a Setin java, from the javadoc

这只是Setjava 中的a 合同,来自javadoc

Returns an iterator over the elements in this set. The elements are returned in no particular order (unless this set is an instance of some class that provides a guarantee). So an implementation of Setisn't required to maintain any order in the values.

返回此集合中元素的迭代器。元素没有特定的顺序返回(除非这个集合是某个提供保证的类的实例)。因此Set不需要实现 来维护值中的任何顺序。

In order to return values in order the Setneeds to maintain the order. This has costs for speed and space.

为了返回值顺序Set需要维护顺序。这有速度和空间的成本。

A LinkedHashSetmaintains insertion order.

ALinkedHashSet维护插入顺序。

回答by Audrius Meskauskas

HashSet does not preserve the element addition order. First it computes the object hash code that should stay constant but is difficult to predict, and then uses it to select a bucket that is a list of objects that have had the same bucket selected. As an Iteratorjust iterates over all buckets, the iteration order is largely unpredictable.

HashSet 不保留元素添加顺序。首先,它计算应该保持不变但难以预测的对象哈希码,然后使用它来选择一个桶,该桶是已选择相同桶的对象列表。由于Iterator只是在所有桶上迭代,迭代顺序在很大程度上是不可预测的。

Use LinkedHashSetinstead if you need to preserve the order. However LinkedHashSetmaintains an additional linked list so needs more resources.

如果您需要保留顺序,请改用LinkedHashSet。但是LinkedHashSet维护一个额外的链表所以需要更多的资源。

回答by Grzegorz Piwowarek

Because in HashSet there is a hash value calculated for each object and this hash value determines the array index of the particular object in the container. So the order of inserted elements are naturally not preserved. This allows for accessing desired elements with O(1) complexity but it costs a lot of memory.

因为在 HashSet 中,为每个对象计算了一个哈希值,这个哈希值决定了容器中特定对象的数组索引。所以插入元素的顺序自然不会保留。这允许访问具有 O(1) 复杂度的所需元素,但它会消耗大量内存。

http://en.wikipedia.org/wiki/Hash_table

http://en.wikipedia.org/wiki/Hash_table

回答by Matt Crinklaw-Vogt

A HashSetuses what is referred to as a hash tableto store items.

AHashSet使用所谓的哈希表来存储项目。

A hash table is made up of several "slots" into which your items are put. Deciding what slot to put an item into is determined by that item's hash code which generally has no relationship to the natural ordering of the item.

哈希表由几个“槽”组成,您的项目将放入其中。决定将项目放入哪个插槽由该项目的哈希码决定,该哈希码通常与项目的自然顺序无关。

A TreeSet, on the other hand, stores items based on their natural ordering which allows an in-order traversal of its contents. This order will be based on the natural ordering of the objects and not the order in which they were inserted. Another difference between a TreeSetand HashSetis that a HashSetprovides O(1) lookup, insertion and removal where as a TreeSetprovides O(log(n))lookup, insertion and removal.

A TreeSet,另一方面,根据项目的自然顺序存储项目,这允许按顺序遍历其内容。此顺序将基于对象的自然顺序,而不是它们插入的顺序。aTreeSetHashSeta之间的另一个区别是 aHashSet提供 O(1) 查找、插入和删除,而 aTreeSet提供O(log(n))查找、插入和删除。

A LinkedHashSetmaintains insertion order of items by constructing links between the elements as they are inserted.

LinkedHashSet通过,因为它们被插入构成元件之间的链接维护项的插入顺序。

回答by Dmitry Gapkalov

Here is ordered version:

这是订购的版本:

import java.util.Set;
import java.util.Iterator;
import java.util.Collections;
import java.util.LinkedHashSet;

 public class HS {
     public static void main(String args[]) {
         Set<String> h=Collections.synchronizedSet(new LinkedHashSet<String>());
         h.add("Mayank");
         h.add("Mayank");

         h.add("Vashist");
         h.add("Dinesh");

         h.add("Vashist");

         Iterator<String> itr=h.iterator();
         while(itr.hasNext()) {
             System.out.println(itr.next());
         }
     }
 }

回答by Juned Ahsan

From the official documentation:

来自官方文档:

This class implements the Set interface, backed by a hash table (actually a HashMap instance). It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time. [...] The iterators returned by this class's iterator method are fail-fast: if the set is modified at any time after the iterator is created

这个类实现了 Set 接口,由一个哈希表(实际上是一个 HashMap 实例)支持。它不保证集合的迭代顺序;特别是,它不保证订单会随着时间的推移保持不变。[...] 此类的迭代器方法返回的迭代器是快速失败的:如果在创建迭代器后的任何时间修改了集合