String中hashCode方法

本文介绍了一种计算字符串HashCode的方法,通过将每个字符乘以31的幂次并累加得到最终的HashCode值。此方法适用于Java环境,有助于提高字符串查找效率。

算法:s[0]*31^(n-1) + s[1]*31^(n-2) + … + s[n-1]
s[i]表示字符串的第i个字符,n表示字符串的长度,^表示取幂。

返回字符串的hashCode,int类型。 方法中hash初始值为0,value为输入的字符串转化为charArray。

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

思考:
Java中HashCode的作用。

了解更多

Java 中,`String.hashCode()` 是 `String` 类的一个方法,用于返回该字符串的哈希码(hash code)。这个哈希码是一个整数,通常用于哈希表(如 `HashMap`、`HashSet` 等)中快速定位对象。 ### 原理 Java 中 `String` 的 `hashCode()` 方法是根据字符串的内容计算出来的。其计算公式如下: $$ s[0] \times 31^{(n-1)} + s[1] \times 31^{(n-2)} + \ldots + s[n-1] $$ 其中: - `s[i]` 是字符串中第 `i` 个字符的 Unicode 值。 - `n` 是字符串的长度。 - 使用了质数 `31` 作为乘法因子,有助于减少哈希冲突。 这个计算是惰性求值的:第一次调用时计算并缓存结果,后续直接返回缓存值(避免重复计算)。 --- ### 源码实现(Java) ```java 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; } ``` > 注:`value` 是存储字符的字符数组,`hash` 是缓存字段(初始为 0)。 --- ### 示例代码 ```java public class StringHashCodeExample { public static void main(String[] args) { String str1 = "hello"; String str2 = "hello"; String str3 = new String("hello"); System.out.println(str1.hashCode()); // 输出: 99162322 System.out.println(str2.hashCode()); // 输出: 99162322 System.out.println(str3.hashCode()); // 输出: 99162322 // 内容相同,hashCode 相同,即使对象不同 System.out.println(str1 == str2); // true (常量池) System.out.println(str1 == str3); // false System.out.println(str1.equals(str3)); // true System.out.println(str1.hashCode() == str3.hashCode()); // true } } ``` --- ### 解释 - 尽管 `str1` 和 `str3` 是不同的对象(内存地址不同),但它们内容相同,因此 `equals()` 返回 `true`,且 `hashCode()` 也必须一致 —— 这是 Java 的约定:**如果两个对象通过 `equals()` 判定相等,则它们的 `hashCode()` 必须相同**。 - `hashCode()` 被广泛用于集合类如 `HashMap` 的 key 查找。例如,`"hello"` 作为 key 存入 `HashMap`,会先通过 `hashCode()` 找到桶位置,再用 `equals()` 确认是否真正匹配。 --- ### 注意事项 1. **不是加密或不可逆**:`hashCode()` 可被轻易逆向推导出可能的输入(尤其是短字符串),不能用于安全目的。 2. **跨 JVM 不一定一致**:虽然算法固定,但在某些特殊实现中可能有差异(一般不会)。 3. **碰撞存在**:不同字符串可能有相同的哈希值,例如: ```java String a = "Aa"; String b = "BB"; System.out.println(a.hashCode()); // 2112 System.out.println(b.hashCode()); // 2112 ``` 这叫“哈希碰撞”,是正常现象。 --- ### 自己实现一个与 String.hashCode 一致的函数 ```java public static int myHashCode(String str) { int h = 0; for (int i = 0; i < str.length(); i++) { h = 31 * h + str.charAt(i); } return h; } // 测试 System.out.println(myHashCode("hello")); // 99162322 System.out.println("hello".hashCode()); // 99162322 ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值