class temp {
int id;
public int getId() {
return id;
}
temp(int id) {
this.id = id;
}
public void setId(int id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
temp other = (temp) obj;
if (id != other.id)
return false;
return true;
}
}
public class testClass {
public static void main(String[] args) {
temp t1 = new temp(1);
temp t2 = new temp(1);
System.out.println(t1.equals(t2));
Set<temp> tempList = new HashSet<temp>(2);
tempList.add(t1);
tempList.add(t2);
System.out.println(tempList);
}
该程序将两个元素都添加到Set中。起初我很震惊,因为在向set添加方法时,调用了equals方法。
但是后来我覆盖了hashCode方法:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
return result;
}
然后它没有添加。这是令人惊讶的,因为Set和add()方法的Javadoc表示,它在向集合中添加时只检查equals()。
这是add()的javadoc:
/**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element <tt>e</tt> to this set if
* this set contains no element <tt>e2</tt> such that
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
* If this set already contains the element, the call leaves the set
* unchanged and returns <tt>false</tt>.
*
* @param e element to be added to this set
* @return <tt>true</tt> if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
然后我意识到HashSet被实现为一个HashMap,在这个map中,对象的hashCode被用作键。因此,如果不重写哈希代码,则使用不同的键来处理它们。
这不应该在add()方法或HashSet的文档中吗?
如果重写equals(),则还必须重写hashCode()。
对于equals()和hashCode()的行为有一些限制,它们在对象的文档中列举。特别是,equals()方法必须显示以下属性:
有关更多详细信息,请参见此。
只需看一下文档:
请注意,每当重写hashCode方法时,通常都需要重写该方法,以便维护hashCode方法的一般约定,即相等的对象必须具有相等的哈希代码。
事实上,equals()和hashCode()是紧密联系在一起的。在与其中一个合作时,应始终考虑这两个方面,以避免这些一致性问题。
它有点记录在案。请参阅java.lang.对象的留档,它在hashCode()
上说:
如果两个对象根据equals(Object)方法相等,则在两个对象中的每一个上调用hashCode方法必须产生相同的整数结果。
此外,以下内容可在对象的文档中找到。等于(对象)方法:
请注意,每当重写hashCode方法时,通常都需要重写该方法,以便维护hashCode方法的一般约定,即相等的对象必须具有相等的哈希代码。
换句话说,如果在类中使用instanceA。等于(instanceB)==true和instanceA。hashCode()!=istanceB。hashCode()您实际上违反了对象类的约定。
问题内容: 该程序将两个元素都添加到集合中。起初我很震惊,因为在添加设置方法时,调用了equals方法。 但是后来我覆盖了hashCode方法: 然后没有添加。这是令人惊讶的,因为Set和add()方法的Javadoc说它在添加到Set中时仅检查equals()。 这是add()的javadoc: 然后我意识到HashSet被实现为HashMap,并且在地图中,对象的hashCode用作键。因此,
问题内容: 我似乎无法使实例正常工作。我使用的代码如下: 子类 该代码输出 问题答案: 您需要覆盖。而不是这样做,您实现了一个带有signature 的方法。因此,您使用的是为相等性测试定义的默认方法。 默认实现基于对象标识,因此,该集合“允许”您添加两个在语义上相等的不同对象。
我正在检查< code>HashSet的< code>add方法。有人提到 如果该集合已经包含元素,则调用保持集合不变,并返回false。 但是方法在内部保存中的值 的方法声明 将指定值与该映射中的指定键相关联。如果映射先前包含该键的映射,则旧值将被替换。 那么,如果 的 方法替换了旧值,那么 方法如何在元素重复的情况下保持集合不变?
} ========================================================================================== 我希望HashSet调用equal方法,因为重写了hashCode。在equals compare之后,我想删除我要传递到hashSet的集合中的重复项。 在控制台中,它将我打印出来,为true(因为在equals
问题内容: 假设您有一个类,并创建了一个HashSet来存储此类的实例。如果尝试添加相等的实例,则集合中仅保留一个实例,这很好。 但是,如果HashSet中有两个不同的实例,并采用一个实例并使其与另一个实例完全相同(通过复制字段),则HashSet将包含两个重复的实例。 这是演示此代码的代码: 上面代码的输出: 有没有一种方法可以强制HashSet验证其内容,以便删除在上述情况下创建的可能重复条目
本文向大家介绍插入Delete GetRandom O(1)-C ++中允许重复,包括了插入Delete GetRandom O(1)-C ++中允许重复的使用技巧和注意事项,需要的朋友参考一下 假设我们要创建一个支持某些操作的数据结构,这些操作必须在O(1)的时间内执行。所以让这些操作像- insert(x):将x插入集合 remove(x):从集合中删除x getRandom():这将找到该集