值大小相同的Integer和Long为什么hashCode值一样

本文深入解析了Java中Integer和Long的hashCode方法实现,通过无符号右移和异或运算来生成哈希码。无符号右移在正数和负数上的不同表现,以及异或运算的规则在哈希码计算中的应用,使得相同的数值能生成一致的哈希值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于Interger和Long的hashCode方法源码

    /**
     * Returns a hash code for this <code>Integer</code>.
     *
     * @return  a hash code value for this object, equal to the 
     *          primitive <code>int</code> value represented by this 
     *          <code>Integer</code> object. 
     */
    public int hashCode() {
	return value;
    }
    /**
     * Returns a hash code for a {@code long} value; compatible with
     * {@code Long.hashCode()}.
     *
     * @param value the value to hash
     * @return a hash code value for a {@code long} value.
     * @since 1.8
     */
    public static int hashCode(long value) {
        return (int)(value ^ (value >>> 32));
    }

位运算:

无符号右移运算符:

右移运算分为两种,分别是带符号右移和无符号右移。现在再来讲解无符号右移。无符号右移运算符的写法是”>>>”,比带符号右移多了一个”>”。带符号右移的运算规则与无符号右移的运算规则差别就在于:无符号右移在二进制串移动之后,空位由0来补充,与符号位是0还是1毫无关系,如下图:

以上图片展示了无符号右移的运算规则。对于正数而言,无符号右移和带符号右移没有什么区别,而对于负数而言,经过无符号右移会产生一个正数,因为最左边的符号位被0填充了。

异或运算:

按位异或运算符写法是”^”,它的运算规则如下图:

如上图,运算规则为:两个二进制位上的数字如果相同,则运算结果为0,如果两个二进制位上的数字不相同,则运算结果为1。下面我们还是用5和6为例来讲解一下异或的运算过程,如下图:

首先还是把这两个数字转换成补码形式,之后把相应的二进制位上的数字进行异或运算,如果对应的两个二进制位上的数相同,计算结果为0,否则计算结果为1。按照这个规则把每一位上的数字都计算一遍后,得到二进制的运算结果是11,这个运算结果转换为十进制数是3。

参考文章:https://blog.youkuaiyun.com/shalimu/article/details/104308769

了解完成两个运算符之后,再来看看hashCode值,上代码:

package com.springboot.test;

import java.util.LinkedList;

public class LongTest {
    public static void main(String[] args) {

        int num = 33;
        String s = getBinary(num);
        System.out.println("初始值: " + s + "  value: " + num);
        for (int i = 1;i<100; i++) {
            int newNum = num >>> i;
            System.out.println("i的值: "+ i + " 二进制:" + getBinary(newNum) + "  value: " + newNum);
        }
    }

    /**
     * 讲10 进制转化为二进制
     * @param num :待转换的十进制
     * @return   :转换后的二进制(string)
     */
    public static String getBinary(int num) {
        int currentNum = num;//存放当前的被除数
        LinkedList<String> list = new LinkedList<String>();//存放余数,也是就二进制数

        while (currentNum != 0) {
            if (currentNum % 2 == 0) {
                list.addFirst("0");
            } else {
                list.addFirst("1");
            }
            currentNum /= 2;
        }

        StringBuilder sb = new StringBuilder();//当然你可以使用其他形式作为方法的返回
        for (int i = 0; i < list.size(); i++) {
            sb.append(list.get(i));
        }
        return sb.toString();
    }

}

查看输出结果:

E:\setup\jdk\jdk\bin\java.exe -javaagent:E:\setup\idea\ideaSetup\lib\idea_rt.jar=56098:E:\setup\idea\ideaSetup\bin -Dfile.encoding=UTF-8 -classpath E:\setup\jdk\jdk\jre\lib\charsets.jar;E:\setup\jdk\jdk\jre\lib\deploy.jar;E:\setup\jdk\jdk\jre\lib\ext\access-bridge-64.jar;E:\setup\jdk\jdk\jre\lib\ext\cldrdata.jar;E:\setup\jdk\jdk\jre\lib\ext\dnsns.jar;E:\setup\jdk\jdk\jre\lib\ext\jaccess.jar;E:\setup\jdk\jdk\jre\lib\ext\jfxrt.jar;E:\setup\jdk\jdk\jre\lib\ext\localedata.jar;E:\setup\jdk\jdk\jre\lib\ext\nashorn.jar;E:\setup\jdk\jdk\jre\lib\ext\sunec.jar;E:\setup\jdk\jdk\jre\lib\ext\sunjce_provider.jar;E:\setup\jdk\jdk\jre\lib\ext\sunmscapi.jar;E:\setup\jdk\jdk\jre\lib\ext\sunpkcs11.jar;E:\setup\jdk\jdk\jre\lib\ext\zipfs.jar;E:\setup\jdk\jdk\jre\lib\javaws.jar;E:\setup\jdk\jdk\jre\lib\jce.jar;E:\setup\jdk\jdk\jre\lib\jfr.jar;E:\setup\jdk\jdk\jre\lib\jfxswt.jar;E:\setup\jdk\jdk\jre\lib\jsse.jar;E:\setup\jdk\jdk\jre\lib\management-agent.jar;E:\setup\jdk\jdk\jre\lib\plugin.jar;E:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值