Java returns null 中的 hashCode 覆盖使用 hashmap 和获取新创建的对象时

hashCode override in Java returns null when using hashmap and getting newly created objects

我目前正在通过 MOOC 学习 Java 的哈希码并按照他们的教程进行操作。但是,当 hashmap 中显然有一个值时,预期输出 returns null。我的覆盖代码如下:


public class Plate{
    private final String regCode;
    private final String country;

    // Counstructors
    ...

    // accessors... only showing name for less clutter
    getCode() 
    getCountry()

    @Override // toString
    public String toString(){
        return country + " " + regCode;
    }

    @Override // equals
    public boolean equals(Object obj){
        if(obj == null){
            return false;
        }   

        if(getClass() != obj.getClass()){
            return false;
        }

        Plate cmp = (Plate) obj;

        if(this.country.equals(cmp.getCountry())){
            return false;
        }

        if(this.regCode == null || this.regCode.equals(cmp.getCode())){
            return false;
        }

        return true;
    }

///////////////////////////////////// Below code may be the problem ///////////////////////////////////
    @Override // hashCode 
    public int hashCode(){
        if(this.country == null || this.regCode == null){
            return 7;
        }   

        return this.country.hashCode() + this.regCode.hashCode(); 

    }
}

我使用上面代码的主要功能是:

import java.util.ArrayList;
import java.util.HashMap;

public class Regi{
    public static void main(String[] args){
        Plate reg1 = new Plate("FI", "ABC-123");
        Plate reg2 = new Plate("FI", "UXE-465");
        Plate reg3 = new Plate("D", "B WQ-431");

        ArrayList<Plate> finnish = new ArrayList<Plate>();
        finnish.add(reg1);
        finnish.add(reg2);

        Plate newPlate = new Plate("FI", "ABC-123");
        if(!finnish.contains(newPlate)){
            finnish.add(newPlate);
        }
        System.out.println("Finnish " + finnish);


// where unexpected result occur
        HashMap<Plate, String> owners = new HashMap<Plate, String>();
        owners.put(reg1, "Arto");
        owners.put(reg3, "Jurgen");

        System.out.println("Owners:");
        System.out.println(owners.get(reg1));
        System.out.println(owners.get(new Plate("FI", "ABC-123")));
        System.out.println(owners.get(new Plate("D", "B WQ-431")));

    }
}

预期输出为:

但是每当我 运行 System.out.println(owners.get(new Plate("FI", "ABC-123")));System.out.println(owners.get(new Plate("D", "B WQ-431"))); 时,我的输出在 "owners:" 部分下方显示 null。我不确定我的自定义 hashCode 函数有什么问题,因为我能够打印出 countryregCode 的 hashCode 并且它们都给出了数值。我还引用了其他人的 post 关于使用素数的哈希码,但它仍然显示为空。我想知道是否有人可以指出有关 hashCode 的正确方向。

您的代码不起作用,因为当两个对象具有 相同 [=15 时,您使 equals return false =].或者一样regCode:

if(this.country.equals(cmp.getCountry())){
    return false;
}

if(this.regCode == null || this.regCode.equals(cmp.getCode())){
    return false;
}

您缺少 !(NOT)运算符:

if (! this.country.equals(cmp.getCountry())) {
    return false;
}

if (this.regCode == null || ! this.regCode.equals(cmp.getCode())) {
    return false;
}

此外,您的 hashCode() 实现意味着 country 可以是 null,因此您缺少空值检查:

if (this.country == null || ! this.country.equals(cmp.getCountry())) {
    return false;
}