java.util.HashSet中的contains()方法不';i don’我没料到会这样

java.util.HashSet中的contains()方法不';i don’我没料到会这样,java,hashset,Java,Hashset,这是java main()方法: 我的Mapper类是: class Mapper { String word; Integer counter; Mapper (String word, Integer counter) { this.word = word; this.counter = counter; } public boolean equals(Object o) { if ((o instanceof Mapper) &a

这是java main()方法:

我的Mapper类是:

class Mapper {

String word;
Integer counter;

Mapper (String word, Integer counter) {
    
    this.word = word;
    this.counter = counter;
    
}

public boolean equals(Object o) {
    
    if ((o instanceof Mapper) && (((Mapper)o).word == this.word)) {
        
        return true;
        
    }
    
    return false;
    
}

}
结果是:

真的

假的

在这个方法中,我从HashSet规范中读到:“如果这个集合包含指定的元素,则返回true。更正式地说,如果并且仅当这个集合包含一个元素e,使得(o==null?e==null:o.equals(e)),则返回true。”

那么,谁能解释一下我错在哪里?还是


谢谢。

您需要实现适当的
hashCode()
函数

public int hashCode() {
  // equal items should return the same hashcode
}
Java实用程序
Java.util
包含许多依赖哈希的类。允许一个人覆盖他们认为合适的
equals()
,意味着还必须正确覆盖
hashCode()
以匹配

hashCode()
的正确实现将为任何两个对象返回相同的哈希值,其中
equals()
返回true。哈希相关函数先检查哈希值是否相等,然后再检查对象是否相等(以解决哈希冲突)。

说明如果两个对象相等,则它们应该具有相同的哈希代码。像HashSet这样的集合假定这是支持的


Object
equals
hashCode
的实现基于地址(或对象ID)。如果您重写
equals
以进行内容比较,则应重写
hashCode
以基于内容生成哈希。

。。。当您在使用它时,请纠正(或清楚地记录)您的equals,不要对字符串使用引用等式。在这种情况下,由于“asd”在同一类文件中被使用了两次,所以可以不受惩罚。但是如果您从用户输入中读取字符串,例如,第一次比较也会失败。@Dilum:为什么?我知道字符串是在JVM初始化时分开创建的字符串内存池中创建的。@artaxerxe字符串是对象。hashCode()的默认实现是为每个实例返回一个唯一的数字。如果您创建两个字符串ala
a1=新字符串(“a”);a2=新字符串(“a”)
a1==a2可能是
false
,因为它们不是同一个对象(由于两个新调用)。这意味着对于字符串(和其他对象)
a1.equals(a2)
通常更安全。@artaxerxe您所说的仅适用于显式插入的字符串。()。假设您阅读了一个XML文档,得到了一个属性包含“asd”和“0”的元素。这些不是固定的字符串。这是数不清的不使用绳子的案例之一。试着用这个例子来说明我的观点:System.out.println(新映射器(“asd.toUpperCase().toLowerCase(),0).equals(test));只是为了添加一些东西,如果要比较字符串的值,应该使用字符串
equals()
方法(而不是
=
,这是参考测试)。
public int hashCode() {
  // equal items should return the same hashcode
}