2013-06-01 165 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通過在元素插入時構建元素之間的鏈接來維護項目的插入順序。

相關問題