我实施了overriding equals and hashCode correctly。在下面的代码中,当我打印出map和num1时,我可以在控制台中看到它们都有更新的hashCode()。但是当我试图将它从地图中删除时,它表示它是空的。有人可以帮助解释为什么.get()方法找不到它吗?
class Phone {
int number;
Phone(int number) {this.number = number;}
public int hashCode() {
return number;
}
public boolean equals(Object o) {
if (o != null && o instanceof Phone)
return (number == ((Phone)o).number);
else
return false;
}
public static void main(String args[]) {
Map<Phone, String> map = new HashMap<>();
Phone num1 = new Phone(2500);
map.put(num1, "John");
num1.number = 100;
System.out.println(map);
System.out.println(num1);
System.out.println(map.get(num1)); // why does it print null
}
}
答案 0 :(得分:2)
它返回null,因为你已经改变了num1对象的数量,从而改变了它的hashcode。哈希映射使用hashcode()来存储和检索对象,因此当你更改它时,你会在错误的地方寻找一个对象,因为它存储在编号为2500的地方,但是你会在地点100上看它。那是因为你的hashcode返回数字。希望这会有所帮助。
答案 1 :(得分:2)
您创建了一个问题,因为您在将密钥放入Map后对其进行了修改,该密钥是根据编号从哈希码方法中获取的。
清理你的代码。更具体地说,使数字不可变,只通过公共getter方法提供对数字的访问。你不应该允许Map中的键是可变的。
public class MyNumber {
private int number;
public MyNumber(int number) {
this.number = number;
}
public int getNumber(){
return number;
}
@Override
public int hashCode() {
return number;
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof MyNumber) {
return (number == ((MyNumber) o).number);
}
else {
return false;
}
}
@Override
public String toString(){
return this.getClass().getName() + "(" + number + ")";
}
}
我已在主要类中的代码中添加了注释:
import java.util.HashMap;
import java.util.Map;
public class OverrideHashCode {
public void mutableObjectKeys() {
Map<MyNumber, String> map = new HashMap<>();
MyNumber num1 = new MyNumber(2500);
map.put(num1, "Shreya");
System.out.println(map);
System.out.println(num1);
//This line was your issue. You placed the MyNyumber in the map
//The hashcode pulls the number value from MyNumber to hash the entry (2500 )
//Then you change the value of number
//num1.getNumber() = 100;
System.out.println(map);
System.out.println(num1);
//This was hashed at 2500, but you changed the MyNumber to 100 - no match
System.out.println(map.get(num1)); // prints null - not anymore
//Let's put a second object in the Map
map.put(new MyNumber(500), "GroovyIsBetter!");
//When you work with Maps, you are commonly trying to get values out of the map based on the key.
//In this example, our key's are MyNumber(s)
//We have made MyNumber.number immutable (which is good).
//Because you implemented your own hashcode and equals, you can even pull the value out of the map
//with a new MyNumber object that has the same number value as the original key you placed in the map
System.out.println("\n" + map.get(new MyNumber(2500)));
System.out.println(map.get(new MyNumber(500)));
//Now we can remove one of the keys and recheck
//Should come up null
map.remove(new MyNumber(500));
System.out.println(map.get(new MyNumber(500)));
}
public static void main(String... args){
new OverrideHashCode().mutableObjectKeys();;
}