2013-06-01 91 views
1

我使用HashSet来添加元素并检索它们,我知道我不会按照顺序检索数据,但我想知道确切的数据原因为何发生?为什么我们没有在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()); 
    } 


} 
    } 

回答

5

后随时修改 这只是在Java Set合同,从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). 

所以Set的实现不需要维持值的任何命令。

为了返回值以便Set需要维护订单。这对速度和空间都有成本。

A LinkedHashSet维持插入顺序。

1

因为在HashSet的存在为每个对象计算出的散列值和该散列值确定在容器中的特定对象的数组索引。所以插入元素的顺序自然不会被保留。 这允许访问具有O(1)复杂性的期望元素,但是其花费了大量内存。

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

2

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

如果您需要保留订单,请改用LinkedHashSet。但是LinkedHashSet维护一个额外的链表,因此需要更多的资源。

0

从官方文档:

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

1

A HashSet使用所谓的hash table来存储项目。

散列表由多个“插槽”组成,您的项目放入其中。决定插入物品的插槽由该物品的散列码决定,该散列码通常与物品的自然排序无关。

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

A LinkedHashSet通过在元素插入时构建元素之间的链接来维护项目的插入顺序。

相关问题