哈希码哈希地图

时间:2013-08-26 00:57:03

标签: java hashmap equals hashcode

我正在努力学习Java。 Eric Roberts的文章“Java的艺术和科学”有一个编程任务,我们模拟飞行预订控制台。我想通过使用只有城市字符串才能完成的城市类来“分类”。它只有一个字段name,它是一个字符串,但我正在尝试学习如何使用类。

无论如何,那么我必须覆盖City类中的equals方法以避免重复。所以我不得不重写hashCode方法。

现在我的HashMap<City,ArrayList<Flight>>无效了。它找不到某些值,但仍允许重复键。

我的城市equalshashCode覆盖如下。任何人都可以看到我的HashMap出错的原因吗?

/* (non-Javadoc)
 * @see java.lang.Object#equals(java.lang.Object)
 */
@Override
public boolean equals(Object that) {
    // TODO Auto-generated method stub
    if ( this == that ) return true;
    if ( !( that instanceof City) ) return false;
    City aThat = (City) that;
    return (name == aThat.name );
}

@Override
public int hashCode() {
    // TODO Auto-generated method stub
    return name.hashCode();
}

2 个答案:

答案 0 :(得分:3)

对于对象比较,使用equals()而不是==,因为==会比较参考值以确定它们是否指向同一个对象。

@Override
public boolean equals(Object that) {
    //more code
    return (name.equals(aThat.name) );
}

顺便说一下,hashCode()它也是错误的,因为name可能为空,您将获得NullPointerException

@Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

最后一点建议,我建议你不要像hash structure一样使用哈希地图mutable objects中的密钥,因为它的hashCode()会发生变化,并且可能会发生意外行为。最好使用inmutable objects作为关键。如果City类是不可改变的那么它没关系,但如果不是那么就改变它。

答案 1 :(得分:-1)

当检查对象的值是否相同时,不要使用==。而是使用.equals,在你的等于方法中改变==到.equals,

例如

String str1 = "Foo bar";
String str2 = "Foo bar";
str1 == str2 // not always true!
str1.equals(str2) // very true

@Override
public boolean equals(Object that) {
    // TODO Auto-generated method stub
    if ( this == that ) return true;
    if ( !( that instanceof City) ) return false;
    City aThat = (City) that;
    return (name.equals(aThat.name) );   // <--- see edit 
}