Nicksxs's Blog

What hurts more, the pain of hard work or the pain of regret?

0%

# 聊聊 Java 的 equals 和 hashCode 方法

发表于 2021-01-03 更新于 2022-05-15 分类于 java 阅读次数： 阅读次数： Disqus：

Java 中的这个话题也是比较常遇到的，关于这块原先也是比较忽略的，但是仔细想想又有点遗忘了就在这里记一下
简单看下代码
`java.lang.Object#equals`

    public boolean equals(Object obj) {
            return (this == obj);
        }

对于所有对象的父类，`equals` 方法其实对比的就是对象的地址，也就是是否是同一个对象，试想如果像 Integer 或者 String 这种，我们没有重写 `equals`，那其实就等于是在用`==`，可能就没法达到我们的目的，所以像 String 这种常用的 jdk 类都是默认重写了
`java.lang.String#equals`

    public boolean equals(Object anObject) {
            if (this == anObject) {
                return true;
            }
            if (anObject instanceof String) {
                String anotherString = (String)anObject;
                int n = value.length;
                if (n == anotherString.value.length) {
                    char v1[] = value;
                    char v2[] = anotherString.value;
                    int i = 0;
                    while (n-- != 0) {
                        if (v1[i] != v2[i])
                            return false;
                        i++;
                    }
                    return true;
                }
            }
            return false;
        }

然后呢就是为啥一些书或者 `effective java` 中写了 `equals` 跟 `hashCode` 要一起重写，这里涉及到当对象作为 `HashMap` 的 `key` 的时候
首先 `HashMap` 会使用 `hashCode` 去判断是否在同一个槽里，然后在通过 `equals` 去判断是否是同一个 `key`，是的话就替换，不是的话就链表接下去，如果不重写 `hashCode` 的话，默认的 `object` 的`hashCode` 是 `native` 方法，根据对象的地址生成的，这样其实对象的值相同的话，因为地址不同，`HashMap` 也会出现异常，所以需要重写，同时也需要重写 `equals` 方法，才能确认是同一个 `key`，而不是落在同一个槽的不同 `key`.