簡體   English   中英

Java HashSet中的重復項

[英]Duplicates in java HashSet

似乎HashSets中允許重復。 為什么會這樣,我該如何刪除它們,為什么下面的第二個remove()不起作用? 刪除所有重復項的一種方法是new HashSet<>(set) ,但是有沒有更好的方法而不涉及創建新對象?

Set<ArrayList<String>> set = new HashSet<>();
ArrayList<String> a1 = new ArrayList<>();
ArrayList<String> a2 = new ArrayList<>();

a1.add("a");
set.add(a1);
a1.remove("a");

set.add(a2);

System.out.println(set.size());
System.out.println(set);

ArrayList<String> a3 = new ArrayList<>();
for (Object o : set) {
    boolean b = o.equals(a3) && (o.hashCode() == a3.hashCode());
    if (!b) System.out.println(false);
}

set.remove(new ArrayList<String>());
System.out.println(set);
set.remove(new ArrayList<String>());
System.out.println(set);
set.remove(set.iterator().next());
System.out.println(set);
System.out.println(set.iterator().next() == a1);

輸出: set由兩個相等的空列表組成,並且最初不為空的列表無法刪除。

2
[[], []]
[[]]
[[]]
[[]]
true

元素在HashMap中的存儲位置取決於該元素添加時的hashCode

如果在添加元素之后,更改了該元素的屬性,該屬性導致其hashCode發生更改(對於ArrayList元素,則從列表中刪除一個元素就可以做到這一點),嘗試在HashSet中查找該元素(或刪除它)將失敗。

散列會在插入時進行存儲。 如果之后更改對象,則其哈希碼將更改,但已經在其存儲桶中。 由於您將嘗試使用與用於插入的哈希碼不同的哈希碼來檢索該哈希碼,因此無法(直接)進行檢索。

a1.add("a"); 
set.add(a1); // hashed and bucketed
a1.remove("a"); // hash code changes but doesn't affect set

set.add(a2); // hashes to a different place than a1

如果修改Map的鍵或Set的元素,則實際上是在破壞它。 集合無法知道您已更改元素或正確處理它。

如果要修改鍵或元素,則必須先將其刪除,修改並重新添加。

暫無
暫無

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

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