【问题标题】:Why can not I use toString().length() as a hashCode() return?为什么我不能使用 toString().length() 作为 hashCode() 返回?
【发布时间】:2012-10-26 16:32:45
【问题描述】:
public class Dog
{
    int collarID;
    String name;
    public static void main(String[] args){
       Dog d = new Dog();  
       d.name="hose";  
       System.out.print(d.hashCode());            
    }

    public boolean equals(Object arg0)
    {
        if (arg0 instanceof Dog)
        {
            Dog new_name = (Dog) arg0;
            return collarID==new_name.collarID && new_name.name.equals(name);
        }
        return false;
    }

    public int hashCode()
    {
        return toString().length();//StackOverflow
    }
}

我错过了什么?是否因为默认的 toString() 方法而经常调用 hashCode() 方法?

【问题讨论】:

  • @Rohit Jain 的回答解释了堆栈溢出。但我建议不要仅仅为了获取哈希码而生成字符串。在这种情况下,为什么不直接使用collarID ^ String.valueOf(name).hashCode()
  • 这是我在模拟考试中做错的一道题
  • 我明白了。那么,这一定是一个令人讨厌的惊喜。为了将来参考,假设 Java 尝试使默认实现说不相等是一个很好的经验法则,除非您另有说明。这会导致更少的意外行为。为此,未定义 toStringequalshashCode 的类的实例将显示不同的字符串、哈希码并表示它们不相等。

标签: java string collections scjp ocpjp


【解决方案1】:

如果你看到Object类的toString方法的源代码,它看起来像:-

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

所以,它在内部调用hashCode() 方法。现在,由于您已经覆盖了hashCode 方法,它将调用您的类的hashCode 方法,该方法再次调用Object 类的toString 方法。

这肯定会导致StackOverFlowError

你可以在你的类中重写toString 方法,让它工作。

附注:-

但是,您的hashCode 实现应该被设计,考虑到您在equals 方法中使用的属性,以维持contracthashCodeequals 方法之间。在计算 hashCode 时仅使用那些 attributes 来比较 equals 方法中的 instances

有关hashCodeequals 方法的更多详细信息,请参阅这些链接:-

【讨论】:

  • toString() 的默认 impl 可能应该使用默认的 hashCode 代替 (System.identityHashCode())
  • @irreputable。由于toString方法中的当前实例是OP的类,并且他已经覆盖了hashCode方法,所以根据多态性,将调用OP类中的hashCode
猜你喜欢
  • 2015-06-01
  • 2016-09-04
  • 1970-01-01
  • 1970-01-01
  • 2015-03-07
  • 2011-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多