簡體   English   中英

Java HashSet中元素的排序

[英]Ordering of elements in Java HashSet

為什么第二組和第三組保留順序:

Integer[] j = new Integer[]{3,4,5,6,7,8,9};
LinkedHashSet<Integer> i = new LinkedHashSet<Integer>();
Collections.addAll(i,j);
System.out.println(i); 

HashSet<Integer> hi = new HashSet<Integer>(i);
System.out.println(hi); 

LinkedHashSet<Integer> o = new LinkedHashSet<Integer>(hi);
System.out.println(o); 

這是我得到的輸出:

3,4,5,6,7,8,9
3,4,5,6,7,8,9
3,4,5,6,7,8,9

第二個(只使用HashSet )只是巧合。 來自JavaDocs

此類實現Set接口,由哈希表(實際上是HashMap實例)支持。 它不能保證集合的迭代順序; 特別是,它不保證訂單會隨着時間的推移保持不變 該類允許null元素。

第三個( LinkedHashSet設計如下:

Set接口的哈希表和鏈表實現,具有可預測的迭代順序。 此實現與HashSet的不同之處在於它維護了一個貫穿其所有條目的雙向鏈表。 此鏈接列表定義迭代排序,即元素插入集合(插入順序)的順序。 請注意,如果將元素重新插入到集合中,則不會影響插入順序。 (如果s.contains(e)在調用之前立即返回true,則調用s.add(e)時,將元素e重新插入到集合中。)

@Bhhrang的答案很好,但更具體地說, HashSet看起來與LinkedHashSet順序相同的唯一原因是integer.hashCode()碰巧是整數值本身,所以數字恰好按順序排列HashSet內部存儲。 這是高度具體的實現,正如@Behrang所說,真的是巧合。

例如,如果您使用new HashSet<>(4)將桶的初始數量設置為4(而不是16),那么您可能獲得了以下輸出:

HashSet<Integer> hi = new HashSet<Integer>(4);
...
[3, 4, 5, 6, 7, 8, 9]
[8, 9, 3, 4, 5, 6, 7]
[8, 9, 3, 4, 5, 6, 7]

如果你卡在> = 16的值,你可能會得到這樣的東西:

Integer[] j = new Integer[] { 3, 4, 5, 6, 7, 8, 9, 16 };
...
[3, 4, 5, 6, 7, 8, 9, 16]
[16, 3, 4, 5, 6, 7, 8, 9]
[16, 3, 4, 5, 6, 7, 8, 9]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM