当我的对象调用 hascode 方法时

sar*_*nan 1 java

我怀疑何时会为我的对象调用 hashcode method() 。我重写了 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()+"");
            
Run Code Online (Sandbox Code Playgroud)

消息线程.java

公共类消息线程{

    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);
    }

}
Run Code Online (Sandbox Code Playgroud)

消息.Java

public class Messages {

    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }   
}
Run Code Online (Sandbox Code Playgroud)

首先,我尝试覆盖 MessageThread 类中的 hashcode方法,得到以下输出。已更改 hascode

05-02 12:51:14.470: hashcode: 0
05-02 12:51:14.470: hashcode after: 1
Run Code Online (Sandbox Code Playgroud)

然后我尝试在不重写MessageThread 类中的 hascode 方法的情况下得到以下输出。哈希码未更改

05-02 12:53:35.417: hashcode : 1105906440
05-02 12:53:35.417: hashcode after: 1105906440
Run Code Online (Sandbox Code Playgroud)

我有以下问题。

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

  2. 当哈希码更改时,是否会在堆中重新创建对象并创建新的引用,或者当哈希码更改时会产生什么副作用?

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

Ste*_*n C 5

我怀疑何时会为我的对象调用 hashcode method() 。

它不会被 JVM自动调用。相反,它是由库代码(或其他代码)根据该代码的需要来调用的。例如,当使用某个对象作为键时HashMap调用该对象;hashcode例如,当您执行 get、put、remove 等操作时。

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

每当我的实例变量修改时,都会调用 hashcode 方法吗?

不。

当哈希码更改时,是否会在堆中重新创建对象并创建新的引用,或者当哈希码更改时会产生什么副作用?

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

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

对象的哈希码的默认实现如何返回相同的哈希码?

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


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

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

  • hashcode()方法只是一个普通方法,其目的是计算hashcode值。

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

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

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

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

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

  • JVM 不会/不能做任何事情来确保您不会破坏不变量。如果你搞砸了,它不会/无法做任何事情来“修复”它。

  • 没有回调,没有侦听器,没有任何类似的东西可以告诉您(或 )HashMap密钥的哈希码已更改。