回答
看了你的問題更具體:
您不能Set.add添加重複,從Java文檔()或你的意思是?:的addAll
添加指定的元素如果此集合尚未出現(可選操作)。更正式地說,如果該集合不包含元素e2(e == null?e2 == null:e.equals(e2)),則將指定的元素e添加到該集合中。如果此集合已包含該元素,則該呼叫將保持集合不變並返回false。結合對構造函數的限制,這可以確保集合永遠不會包含重複的元素。
實際上,來自java中的源代碼最多的Set
實現的AFAIK甚至不檢查元素是否已被包含。
他們總是在其內部結構上執行add()
,該內部結構持有set元素並讓該對象處理重複情況。
例如HashSet
在內部HashMap
上調用put(K,V)
,它只是插入新對象覆蓋舊條目(如果重複)。
讀一點你的問題我猜你看到奇怪的行爲與java.util.HashSet
(通常是每個人默認使用)。
Contary到java.util.Set
合同有可能得到一個java.util.HashSet
同樣的對象兩次這樣的:
import java.util.HashSet;
import java.util.Set;
public class SetTest
{
public static void main(String[] args)
{
MyClass myObject = new MyClass(1, "testing 1 2 3");
Set<MyClass> set = new HashSet<MyClass>();
set.add(myObject);
myObject.setHashCode(2);
set.add(myObject);
System.out.println(set.size()); // this will print 2.
}
private static class MyClass
{
private int hashCode;
private String otherField;
public MyClass(int hashCode, String otherField)
{
this.hashCode = hashCode;
this.otherField = otherField;
}
public void setHashCode(int hashCode)
{
this.hashCode = hashCode;
}
public boolean equals(Object obj)
{
return obj != null && obj.getClass().equals(getClass()) && ((MyClass)obj).otherField.equals(otherField);
}
public int hashCode()
{
return hashCode;
}
}
}
從@jitter指針,看看源後,你可以看到爲什麼這會發生。
像@jitter說的,java.util.HashSet
在內部使用java.util.HashMap
。當散列在第一個和第二個之間變化時加入在java.util.HashMap
中使用不同的桶並且該對象在該集中兩次。
代碼示例可能看起來有點受損,但我已經看到這種情況發生在域類中,其中哈希是從可變字段創建的,並且equals方法未與這些字段保持同步。
一個簡單的方法來找出這是從源頭爲您感興趣的代碼查找。
每個JDK已經包含了src.zip其中包含了公共類的源代碼,這樣你可以只找到HashSet的源代碼並看看:)我經常使用Eclipse進行此操作。啓動它,創建一個新的Java項目,將JVM設置爲已安裝的JDK(如果不是,則使用系統默認的JRE,它不包含src.zip),並將Ctrl-Shift-T設置爲HashSet。
- 1. java.util.Set中增加了重複的條目
- 2. R中重複元素的元素
- 3. 重複元素
- 4. :元素重複
- 5. 重複的元素
- 6. 重複元素子元素的ID
- 7. WPF重複元素
- 8. 重複gridview元素.....!
- 9. numpy重複元素
- 10. insertAfter重複元素
- 11. 如何刪除java.util.Set中的最後一個元素?
- 12. 重複數組中的元素而不重複相同的元素
- 13. 刪除重複的元素
- 14. Android的listview重複元素
- 15. 重複元素的Richfaces
- 16. 重複的頁面元素
- 17. 刪除重複的元素
- 18. SimpleXML的重複元素
- 19. 重複的html元素
- 20. 使用XSLT連接非重複元素和重複元素
- 21. 如何在Angular中重複ng元素中的元素
- 22. 處理ng-repeat中的重複元素
- 23. X元素數組中的重複項
- 24. 刪除BST中的重複元素
- 25. xml元素中的重複檢查
- 26. 數組算法中的重複元素
- 27. 查找向量中的重複元素
- 28. 查找數組中的重複元素?
- 29. 通用列表中的重複元素
- 30. 刪除列表中的重複元素
以修改hashCode()/ equals()結果的方式修改HashSet中的對象會產生未定義的行爲。 – 2009-10-29 09:34:12
@Joachim - 確切地說,但並不意味着它不會發生。事實上,流行的IDE生成的equals/hashCode方法通常會導致hashCode隨着對象的變化而改變。 – 2009-10-29 09:45:23
如果對象發生了變異,hashcode *應該改變 - 畢竟它需要與equals()一致,所以如果一個對象不再被認爲等於它的預突變狀態,它就需要改變。這裏真正的問題是使用可變對象作爲HashMap鍵; * *建議只使用不可變的對象,否則你打開自己的這種隨機性,因爲一般來說''hashCode()'*必須*隨着可變對象的變化而改變。 – 2009-10-29 10:36:26