Java 如何使用对象作为键搜索hashmap?

Java 如何使用对象作为键搜索hashmap?,java,Java,假设我们有班级注册牌: public class RegistrationPlate { private final String regCode; private final String country; public RegistrationPlate(String country, String regCode) { this.regCode = regCode; this.country = country; } public String getRegCode()

假设我们有班级注册牌:

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

public RegistrationPlate(String country, String regCode) {
    this.regCode = regCode;
    this.country = country;
}

public String getRegCode() {
    return this.regCode;
}

public String getCountry() {
    return this.country;
}

@Override
public String toString() {
    return country + " " + regCode;
}
我有一个hashmap,它的键是RegistrationPlate,值是owner。如果我想搜索这个hashmap,给定一个RegistrationPlate对象作为参数,我会怎么做?我最初是这样做的:

HashMap<RegistrationPlate, owner> vehicleRegister = new HashMap<RegistrationPlate, owner>();


public String getOwner(RegistrationPlate plate) {
    if (this.vehicleRegister.containsKey(plate.getRegCode())) {
        return "The owner is: " + this.vehicleRegister.get(plate);
    }
    return null;
}
HashMap vehiclerregister=newhashmap();
公共字符串getOwner(注册板){
if(this.vehiclerRegister.containsKey(plate.getRegCode())){
return“车主是:”+此.车辆注册器.get(车牌);
}
返回null;
}

我认为这里的逻辑会起作用,因为如果VehiclerRegister包含registrationcode字符串作为密钥,它将返回下面的字符串。在hashmap中是否有更清晰的访问对象的方法

由于
HashMap
RegistrationPlate
作为键,因此不能期望找到作为键的
字符串。这意味着你应该这样做

this.vehicleRegister.containsKey(plate)
而不是

this.vehicleRegister.containsKey(plate.getRegCode())
但是,您可以直接调用
get()
,而无需先调用
containsKey()

public String get(RegistrationPlate plate) {
    return "The owner is: " + this.vehicleRegister.get(plate);
}

更重要的是,您必须在
RegistrationPlate
中重写
equals()
hashcode()
,以获得所需的行为。否则,将使用默认实现,仅当键是对与存储在
HashMap
中的on完全相同的实例的引用时,才会返回
true
。这种情况很少发生。您通常希望比较引用的内容。

您需要同时覆盖
注册板的
equals()
hashCode()

要使用
RegistrationPlate
的对象作为
HashMap
的键,建议覆盖
RegistrationPlate
equals()
hashCode()
方法。如果不重写
equals()
方法,将出现以下情况:

RegistrationPlate rp1 = new RegistrationPlate();
RegistrationPlate rp2 = new RegistrationPlate();

rp1.equals(rp2); // returns false
当您重写
equals()
时,还需要重写
hashCode()
。否则,您将发现由于以下情况,
HashMap
的行为不一致:

RegistrationPlate rp1 = new RegistrationPlate();
RegistrationPlate rp2 = new RegistrationPlate();

rp1.equals(rp2); // returns true (because you overriden equals() method to be so)
rp1.hashCode() == rp2.hashCode(); // will be evaluated to false
boolean equals(Object obj)
int hashCode()
应在
RegistrationPlate
类中重写


HashMap使用
hashCode()
查找存储对象的组;它使用
equals()
来搜索该对象。

如果覆盖equals,还应该确保覆盖hashCode,这样就可以像:return“所有者是:”+this.register.get(plate);?假设我正确地重写了equal和hashcode;如果我调用equals()而不是containsKey(),我上面的代码会正常工作吗?@AeriaGlorisia
equals()
containsKey()
做两件完全不同的事情。“正确性”取决于您的
get()
方法的目的。@AeriaGlorisia请在我最近的编辑中查看代码。这将编译并运行一些输出。但是,您在这里没有提供足够的信息,我无法根据您的项目规范确定输出是否正确。@AeriaGlorisia我要求从您的代码中获取这些类的一个原因是它们可以提供有关用途的线索。例如,在一个更“真实”的示例中,
get()
类似于
getOwner()
,只返回所有者的名称。标签
“所有者是:“
只有在
main()
中实际打印时才会添加。当您了解更多Java时,您将了解更多有关设计概念的知识。祝你好运当您尝试在这里编译和运行代码时会发生什么?什么都没有。编译,但当我在Main中调用它时,它不起作用。你应该在你之前的评论中包含这些信息,作为你问题的一部分。您还应该显示主方法,并将
get()
方法包装到包含它的类中。”假设我们有两个实例变量的对象注册板:“此引号后面的下一行显示的是构造函数,而不是实例变量。如果你给我看一下实际的课程,会有帮助的。它可以在某种程度上被截断以节省空间,但其主要思想是显示可实际编译的代码。这里显示的代码都不符合这个标准,因为没有类。如果我让它工作起来,我还应该考虑包含这些类吗?