zoukankan      html  css  js  c++  java
  • 从解析String的hashCode和equals方法源码到hash冲突

    经常被问到hashcode方法和equals方法还有== ,网上都有结论,但我们不能知其然却不知其所以然。所以我们从string的hashcode和equals入手,探究这3者,先贴源码。

     public int hashCode() {
            int h = hash;
            if (h == 0 && value.length > 0) {
                char val[] = value;
    
                for (int i = 0; i < value.length; i++) {
                    h = 31 * h + val[i];
                }
                hash = h;
            }
            return h;
        }
    hashcode
    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;
        }
    equals

    1.string的hashcode主要代码  h = 31 * h + val[i];

    遍历所有字符,val[i]对应ASCII表中的值,将它与h*31累加。最终得出一个hash值,但我们可以从这个算法得知,不同的字符串有可能得出相同的hashcode值(概率很低)

    比如2个val1[1,0];val2[31]; 我这里直接将ASCII值代替进去了,它们运算后的h都是31,但它们代表的内容不同。

    所以通过hashcode值判断2个字符串是否相等是不行的。

    2.equals方法.

      == : 它的作用是判断两个对象的地址是不是相等

      equals方法先判断2个字符串==,假如2个字符串都==了,就是同一个对象了,肯定就相等了。

      然后遍历2个字符串,一一对应比较字符,假如都相等了,就说这2个字符串内容一样。

    总结:equals方法比较了2个字符串是否是同一个对象,并且比较它们的内容是否一样。

        如果是同一个对象那么内容肯定一致,根据hashcode算法它们的hash值也一样,

        不同对象,它们内容也可能一致,内容一致hash值也就一样,

        但是内容和对象都不一样,它们的hash值有可能相同,这样就出现了所谓的hash冲突。原因取决于hashcode的算法(见1)

    所以通过hash值来比较2个字符串内容是否一致严格上是错误的。

  • 相关阅读:
    1.1 git和github -1 介绍
    seajs使用
    seajs使用-1 解决冲突和依赖
    6. 菜单切换
    5. 背景半透明 元素不透明(兼容所有浏览器)
    4. 父元素如何包含子元素
    3. js 多维数组转为一维数组
    2. 伪数组转为数组 Array.prototype.slice.call(arguments)
    3. 伪元素清除最后一个border的边框
    2. 详解 CSS 属性
  • 原文地址:https://www.cnblogs.com/ljjnbpy/p/10042104.html
Copyright © 2011-2022 走看看