为什么改变 StringBuilder 会改变它的 hashCode?

Why does changing StringBuilder change its hashCode?

这是输入。

    public static void main(String[] args){

        StringBuilder builder = new StringBuilder("hello");
        printBuilder(builder);

        // append
        builder.append(" everyone");
        printBuilder(builder);

        builder.append(", what's up?");
        printBuilder(builder);
    }

    private static void printBuilder(StringBuilder dataBuild){
    StringBuilder build = new StringBuilder(dataBuild);
    System.out.println("data = " + build);
    System.out.println("length = " + build.length());
    System.out.println("capacity = " + build.capacity());
    int addressBuild = System.identityHashCode(build);
    System.out.println("address = " + Integer.toHexString(addressBuild);
    }

这是输出。

为什么地址与其他地址不同? 我虽然会是一样的。我尝试了不同的方式,如插入、替换、charAt,但地址仍然不同。谁能告诉我为什么?

System#identityHashCode不是return对象的地址。

Returns the same hash code for the given object as would be returned by the default method hashCode(), whether or not the given object's class overrides hashCode(). The hash code for the null reference is zero.

class 的每个对象都有不同的哈希码。由于每次调用 printBuilder 都会创建一个新对象,因此您会得到不同的哈希码。

注意:比较使用== returns true 具有相等哈希码的引用。

class Main {
    public static void main(String[] args) {
        Boolean b1 = true;
        Boolean b2 = Boolean.valueOf("true");
        System.out.println(System.identityHashCode(b1));
        System.out.println(System.identityHashCode(b2));
        System.out.println(b1 == b2);

        String s1 = "Hello";
        String s2 = s1;
        String s3 = new String("Hello");// Creates a new object and hence s3 will have a different hash code
        System.out.println(System.identityHashCode(s1));
        System.out.println(System.identityHashCode(s2));
        System.out.println(s1 == s2);
        System.out.println(System.identityHashCode(s3));
        System.out.println(s2 == s3);
    }
}

输出:

992136656
992136656
true
511833308
511833308
true
1297685781
false

printBuild() 中,每次调用都会创建一个新的 StringBuilder。每次为新构建器打印哈希:

int addressBuild = System.identityHashCode(build);

您不能合理地期待不同的结果。如果您希望每次都看到相同的哈希值,请删除以下行:

StringBuilder build = new StringBuilder(dataBuild);

直接对输入参数dataBuild进行操作:它作为引用传入。

详细说明:System.identityHashCode 产生的结果只有在对象相同时才能保证相同(如 ==,而不是 equals())。当然,与任何散列一样,两个不相等的对象可能具有相同的散列,但该函数确实会尝试减少重叠。正如预期的那样,结果通常 基于 内存位置,尽管它通常不是内存位置本身。