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
Why do we not get the ordered sequence in HashSet
提问by Make
I am using the HashSet
for 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 Set
in java, from the javadoc
这只是Set
java 中的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
Set
isn't required to maintain any order in the values.
返回此集合中元素的迭代器。元素没有特定的顺序返回(除非这个集合是某个提供保证的类的实例)。因此
Set
不需要实现 来维护值中的任何顺序。
In order to return values in order the Set
needs to maintain the order. This has costs for speed and space.
为了返回值顺序Set
需要维护顺序。这有速度和空间的成本。
A LinkedHashSet
maintains 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 Iterator
just iterates over all buckets, the iteration order is largely unpredictable.
HashSet 不保留元素添加顺序。首先,它计算应该保持不变但难以预测的对象哈希码,然后使用它来选择一个桶,该桶是已选择相同桶的对象列表。由于Iterator
只是在所有桶上迭代,迭代顺序在很大程度上是不可预测的。
Use LinkedHashSetinstead if you need to preserve the order. However LinkedHashSet
maintains 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) 复杂度的所需元素,但它会消耗大量内存。
回答by Matt Crinklaw-Vogt
A HashSet
uses 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 TreeSet
and HashSet
is that a HashSet
provides O(1) lookup, insertion and removal where as a TreeSet
provides O(log(n))
lookup, insertion and removal.
A TreeSet
,另一方面,根据项目的自然顺序存储项目,这允许按顺序遍历其内容。此顺序将基于对象的自然顺序,而不是它们插入的顺序。aTreeSet
和HashSet
a之间的另一个区别是 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 实例)支持。它不保证集合的迭代顺序;特别是,它不保证订单会随着时间的推移保持不变。[...] 此类的迭代器方法返回的迭代器是快速失败的:如果在创建迭代器后的任何时间修改了集合