当为我的对象调用hashcode方法时

时间:2014-05-02 07:50:56

标签: java

我怀疑是否会为我的对象调用hashcode方法()。 我为MessageThread类重写了hashcode方法。

MainActivity.java

        MessageThread messageThread=new MessageThread();


        Log.e("hashcode", messageThread.hashCode()+"");
        Messages messages=new Messages();

        messageThread.addMessage(messages);
        Log.e("hashcode after", messageThread.hashCode()+"");

MessageThread.java

公共类MessageThread {

    List<Messages> messages = new ArrayList<Messages>();


    public boolean equals(Object o) 
    {

        if((o instanceof MessageThread )&&(((MessageThread)o).getMessages().size()==this.getMessages().size()))
        {
            return true;
        }
        else
        {
            return false;
        }
    }


    public int hashCode()
    {
        return messages.size();
    }

    public List<Messages> getMessages() {
        return messages;
    }


    public void setMessages(List<Messages> messages) {
        this.messages = messages;
    }

    public void addMessage(Messages message)
    {
        messages.add(message);
    }

}

Messages.Java

public class Messages {

    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }   
}

首先,我尝试通过覆盖Class MessageThread中的哈希码方法 我得到了以下输出。 hascode已更改

05-02 12:51:14.470: hashcode: 0
05-02 12:51:14.470: hashcode after: 1

然后我在类MessageThread中尝试而没有覆盖hascode 方法 我得到了以下输出。 哈希码未更改

05-02 12:53:35.417: hashcode : 1105906440
05-02 12:53:35.417: hashcode after: 1105906440

我有以下问题。

  1. 只要修改了实例变量,就会调用hashcode方法吗?

  2. 当哈希码发生变化时,会在堆中重新创建对象,并且会创建新引用,或者当哈希码变为chages时会产生什么副作用?

  3. Object的hashcode的默认实现如何返回相同的hashcode?

2 个答案:

答案 0 :(得分:4)

  

我怀疑是否会为我的对象调用hashcode方法()。

JVM不会自动将称为。相反,它根据代码的需要由库代码(或其他)调用。例如,HashMap在将对象用作键时调用hashcode对象;例如当你做一个get,put,remove等等。

(如果您想观察被调用的hashcode方法,请将对象放入HashSet

  每当我的实例变量被修改时,

会调用hashcode方法吗?

没有

  

当哈希码发生变化时,会在堆中重新创建对象,并且会创建新引用,或者当哈希码变为chages时会产生什么副作用?

当哈希码更改时,不会创建新对象。

如果您的对象的哈希码在用作HashMap中的键时发生更改,(等等)将打破HashMap(等)的不变量。坏!!这很可能打破数据结构。例如,HashMap.get 等操作可能会返回错误答案

  

Object的hashcode的默认实现如何返回相同的hashcode?

一些特别的魔法。阅读以前问题的这些答案:


更新 - 您似乎对哈希码是什么以及hashcode()方法的作用感到困惑。

  • 哈希码值只是一个32位整数。

  • hashcode()方法只是一种普通方法,其目的是计算哈希码值。

  • 要使hashcode()方法有用,它需要符合几个不变量:

    1. 如果两个对象相等(根据equals(Object)),那么他们的hashcode()方法应返回相同的值。

    2. 如果两个对象不相等(根据equals(Object)),那么他们的hashcode()方法返回相同值的概率应非常小。< / p>

    3. 当对象处于散列数据结构时,其哈希码不得更改。

  • 程序员有责任确保满足上述不变量。如果你失败了,你的程序可能会出错。

  • JVM没有/不能做任何事情来确保你不打破不变量。它没有/不能做任何事情&#34;修复&#34;如果你搞砸了。

  • 没有回调,没有听众,也没有告诉你(或HashMap)密钥的哈希码已经改变。

答案 1 :(得分:1)

1.每当我的实例变量被修改时,是否会调用hashcode方法?

  

HashCode方法通常由各种基于哈希的集合调用,以使用哈希码对特定存储桶中的对象进行排序。这有助于从集合中更快地检索Object。有许多方法可以实现哈希码方法。如果您的实现依赖于实例变量,则在修改实例变量时它自然会发生变化。所以没有监听器会在变量发生变化时调用你的hashcode方法。虽然如果任何API确实调用了您的hashcode方法,返回的值也会不同。

2.当哈希码发生变化时,是否会在堆中重新创建对象,并且会创建新引用或者当哈希码变为chages时会产生什么副作用?

请参阅哈希码合约

  

每当在执行Java应用程序期间多次在同一对象上调用它时,hashCode方法必须始终返回相同的整数,前提是不修改对象上的equals比较中使用的信息。
  从整数的执行开始,该整数不需要保持一致   应用于同一应用程序的另一个执行   如果两个对象根据equals(Object)相等   方法,然后在每个上调用hashCode方法   这两个对象必须产生相同的整数结果   如果两个对象不相等,则要求   根据{@link java.lang.Object#equals(java.lang.Object)}   方法,然后在每个上调用hashCode方法   两个对象必须产生不同的整数结果。但是,中   程序员应该意识到产生不同的整数结果   对于不平等的对象可能会提高哈希表的性能。

不正确的哈希码实现的副作用是,如果我们在重新检索对象时无法生成相同的哈希码,那么添加到基于哈希的集合的对象将会丢失。

3.对象的哈希码的默认实现如何返回相同的哈希码? Default HashCode implementation