Dav*_*d M 4 java equals hashcode
我有一个类,我已经覆盖了hashCode方法和equals方法.equals方法的行为与我期望的一样,但hashCode方法似乎没有像我期望的那样运行.我假设因为我的期望是不正确的,但不知道为什么.以下是重写方法:
public class Car extends SomeBaseClass implements Cloneable, Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String name;
private String carName;
private String carModel;
private String displayTextCar;
public boolean equals(Car car)
{
return (getCarName().equals(car.getCarName()) && getCarModel().equals(car.getCarModel()));
}
public int hashCode()
{
return (this.getCarName() + this.getCarModel()).hashCode();
}
Run Code Online (Sandbox Code Playgroud)
现在我有一个测试类,在其中创建两个car对象,并调用equals方法,然后将每个car实例放入HashMap.我将每个实例设置为具有相同的汽车名称和模型,并且调用equals方法实际上返回true.然而,即使每个实例返回相同的hashCode,当我将它们添加到HashMap时,它将两个对象保留在Map中,而我希望第二个put替换地图中的第一个对象??? 以下是测试类的内容:
HashMap<Car,String> testMap;
Car testCar1 = new Car();
testCar1.setCarName("DaveCar");
testCar1.setCarModel("DaveModelTest");
System.out.println("Car Hash 1: " + testCar1.hashCode());
Car testCar2 = new Car();
testCar2.setCarName("DaveCar");
testCar2.setCarModel("DaveModelTest");
System.out.println("Car Hash 2: " + testCar2.hashCode());
//hashCodes prints identical numbers
System.out.println("Car 1 equal Car 2 ?? " + testCar1.equals(testCar2));
//returns true
testMap.put(testCar1, "3");
testMap.put(testCar2, "16");
System.out.println("Map size is " + testMap.size());
//I would expect the size to be 1 here, but it's in fact 2.
Run Code Online (Sandbox Code Playgroud)
所以这对我来说似乎不正确,我自然会在这里留下一些代码,但这是基本原则.希望有人能指出我在哪里出错了.请注意,我确实使用Eclipse来生成hashCode和equals方法并且这些方法正常工作,但是我的错误是我的hashCode实现没有按照我的预期工作,即使两个对象看起来都返回了hashCode的相同值.感谢任何人的意见.
das*_*ght 15
问题是你提供了一个错误equals:应该是equals(Object),而不是equals(Car).
本质上,您提供了一个重载而不是重写,因此HashMap不断调用equals基类.
解决这个问题很简单:添加一个执行转换的覆盖,并调用equals您编写的方法,如下所示:
@Override
public boolean equals(Object other) {
return (other instanceof Car) && equals((Car)other);
}
Run Code Online (Sandbox Code Playgroud)
注意使用@Override注释.它有助于Java帮助您自动发现此类问题.
注意:考虑到这个问题,请考虑hashCode以更"节俭"的方式实现您的方法.不是(this.getCarName() + this.getCarModel())为了获取其哈希码而创建一个丢弃字符串,而是考虑重写方法如下:
public int hashCode() {
return 31*getCarName().hashCode() + getCarModel().hashCode();
}
Run Code Online (Sandbox Code Playgroud)
或者在Java 1.7+中你可以写
public int hashCode() { // Thanks, fge, for a nice improvement!
return Objects.hash(carName, carModel);
}
Run Code Online (Sandbox Code Playgroud)
问题不在于.hashCode(); 问题是你不要覆盖.equals()!
看看你的原型:
public boolean equals(Car car)
Run Code Online (Sandbox Code Playgroud)
现在看一下... 的文档Object
你应该覆盖的是:
public boolean equals(Object obj)
Run Code Online (Sandbox Code Playgroud)
因此错误.您确实正确实现了hashCode,但是您使用Object的是.equals()实现.