java.util.Set
实现删除了重复的元素。
如何在java.util.Set
??
答案 0 :(得分:14)
实际上来自Java中大多数Set
实现的来源的AFAIK甚至不检查该元素是否已被包含。
他们总是在其内部结构上执行add()
,它保存set元素并让该对象处理重复的情况。
e.g。 HashSet
在内部put(K,V)
上调用HashMap
,如果重复,则会插入新对象覆盖旧条目。
答案 1 :(得分:10)
稍微阅读一下你的问题我猜你用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;
}
}
}
在指向@jitter并查看源代码后,您可以看到为什么会发生这种情况。
就像@jitter所说,java.util.HashSet
在内部使用java.util.HashMap
。当第一个和第二个 add 之间的哈希值发生变化时,java.util.HashMap
中使用了另一个桶,并且该对象在该集合中两次。
代码示例可能看起来有点受欢迎,但我已经看到这种情况发生在域类中,其中哈希是从可变字段创建的,并且equals方法尚未与这些字段保持同步。
答案 2 :(得分:2)
找到这个的简单方法是查看您感兴趣的代码的来源。
每个JDK都包含一个src.zip,其中包含公共类的源代码,因此您只需找到HashSet的源代码并查看:)我经常使用Eclipse。启动它,创建一个新的Java项目,将JVM设置为已安装的JDK(如果没有使用系统默认的JRE,它没有src.zip),并按Ctrl-Shift-T转到HashSet。
答案 3 :(得分:0)
更详细地阅读您的问题:
你不能在java doc for Set.add()中添加重复项,或者你的意思是addAll?:
如果指定的元素尚不存在,则将其添加到此集合中(可选操作)。更正式地,如果集合不包含元素e2,则将指定的元素e添加到该集合中(e == null?e2 == null:e.equals(e2))。如果此set已包含该元素,则调用将保持set不变并返回false。结合对构造函数的限制,这可以确保集合永远不会包含重复元素。
答案 4 :(得分:0)
如果指定的元素尚不存在,则将其添加到集合中。 如果该集合已经包含该元素,则调用将使该集合保持不变并返回false。结合构造函数的限制,这将确保该集合永远不会包含重复的元素。