假设我们有类注册板:
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> 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;
}
我认为这里的逻辑会起作用,因为如果车辆注册包含注册码字符串作为键,它将返回下面的字符串。有没有更简洁的方式来访问哈希图中的对象?
您需要同时覆盖equals()
和hashCode()
RegistrationPlate
。
要使用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
由于HashMap
具有RegistrationPlate
键,因此您不能期望找到作为键的String
。这意味着你应该这样做
this.vehicleRegister.containsKey(plate)
而不是
this.vehicleRegister.containsKey(plate.getRegCode())
但是,您可以直接呼叫get()
,而无需先呼叫containsKey()
:
public String get(RegistrationPlate plate) {
return "The owner is: " + this.vehicleRegister.get(plate);
}
更重要的是,您必须覆盖equals()
和hashcode()
RegistrationPlate
才能获得所需的行为。否则,将使用默认实现,仅当键是对与存储在HashMap
中的 on 完全相同的实例的引用时才返回true
。这种情况很少见。您通常希望改为比较引用的内容。
boolean equals(Object obj)
和int hashCode()
应该在RegistrationPlate
类中被覆盖。
HashMap 使用hashCode()
来查找存储对象的组;它使用equals()
来搜索该对象。