jit*_*ter 14
实际上来自SetJava中大多数实现的来源的AFAIK 甚至不检查该元素是否已被包含.
它们总是执行add()内部结构,它保存set元素并让该对象处理重复的情况.
例如,对内部的HashSet调用只是插入新对象,如果重复则覆盖旧条目.put(K,V)HashMap
Nic*_*olt 11
仔细阅读你的问题我猜你正在看到一个奇怪的行为java.util.HashSet(通常是每个人默认使用的).
对它的合同的合同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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在来自@jitter的指针并查看源代码后,您可以看到为什么会发生这种情况.
就像@jitter说的那样,内部java.util.HashSet使用了一个java.util.HashMap.当第一和第二之间的散列变化添加不同的桶在使用java.util.HashMap和对象是在该组的两倍.
代码示例可能看起来有点受欢迎但我已经看到这种情况发生在域类中,其中哈希是从可变字段创建的,并且equals方法未与这些字段保持同步.
更详细地阅读您的问题:
您无法添加重复项,来自 Set.add() 的 java doc 还是您的意思是 addAll?:
如果指定元素尚不存在,则将其添加到该集合中(可选操作)。更正式地说,如果集合不包含满足 (e==null ? e2==null : e.equals(e2)) 的元素 e2,则将指定元素 e 添加到此集合中。如果该集合已包含该元素,则调用将保持该集合不变并返回 false。与构造函数的限制相结合,这可以确保集合永远不会包含重复的元素。
| 归档时间: |
|
| 查看次数: |
46468 次 |
| 最近记录: |