Java不重写hashCode()方法,可不可能两个不同的对象hashCode相同?

SiegfriedG 2020-06-25 07:10:40
我知道不重写hashCode()方法的话,是用对象内存地址值来计算hashCode的(但Object的hashCode方法是个native方法,看不到源码),但现在有个疑问,
有人说:因此不同对象的hashCode值肯定不一样,
又有人说:不同对象的hashCode可能一样。
但是都给不出确切的理由。
那不同对象的hashCode到底可不可能相同呢?
麻烦不要复制粘贴一大堆。
...全文
4594 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
God_zmd 2021-03-30
  • 打赏
  • 举报
回复
为什么必须要重谢hashcode方法,是equals的时候会用到hashcode嘛?
  • 打赏
  • 举报
回复
请问答案和原因是什么啊?
游北亮 2020-08-11
  • 打赏
  • 举报
回复
了解下HashCode的定义,就会知道为什么可能存在相同了。
PrivateInterface 2020-08-10
  • 打赏
  • 举报
回复
这个是可能的,hashCode只是尽量会满足不同的地址有不同的哈希值,但是在很低概率的情况下,就会出现相同的哈希值,例如在Set集合的hashSet的源码中就是先判断哈希值是否相同,在通过equals比较以确定两个元素不会重复
SiegfriedG 2020-06-27
  • 打赏
  • 举报
回复
引用 10 楼 sotondolphin 的回复:
当然可能啊, 两个不同的对象可能有相同的hash code

都说了已经解决了,不用再回复了。
况且你这只是一句结论,没有原因,说了等于没说啊。
sotondolphin 2020-06-27
  • 打赏
  • 举报
回复
当然可能啊, 两个不同的对象可能有相同的hash code
卖水果的net 2020-06-27
  • 打赏
  • 举报
回复
引用 8 楼 SiegfriedG 的回复:
[quote=引用 7 楼 卖水果的net 的回复:]

最简单的例子

    public static void main(String[] args) {
        Long x = -1L;
        Long y = 0L;
        System.out.println(x.hashCode());
        System.out.println(y.hashCode());
    }

你这也是重写了hashCode方法,源码是这样的: public static int hashCode(long value) { return (int)(value ^ (value >>> 32)); } 我问的是不重写的情况。不过现在已经解决了。 [/quote]
SiegfriedG 2020-06-27
  • 打赏
  • 举报
回复
引用 7 楼 卖水果的net 的回复:

最简单的例子

public static void main(String[] args) {
Long x = -1L;
Long y = 0L;
System.out.println(x.hashCode());
System.out.println(y.hashCode());
}


你这也是重写了hashCode方法,源码是这样的:
public static int hashCode(long value) {
return (int)(value ^ (value >>> 32));
}
我问的是不重写的情况。不过现在已经解决了。
faith.huan 2020-06-26
  • 打赏
  • 举报
回复
引用 2 楼 SiegfriedG的回复:
[quote=引用 1 楼 faith.huan 的回复:]
答案肯定是可能相同的,如下s1,s2就不是同一对象,但他们有相同hashcode

String s1= new String("s");
String s2= new String("s");
System.out.println(s1 == s2);
System.out.println(s1.hashCode() == s2.hashCode());

我上来就说了【不重写hashCode的情况下】啊,String重写了hashCode和equals,用字符串内容做标准,肯定有这种情况。我问的是不重写,用原始Object内存地址来hash的情况。麻烦看清题目。[/quote] 不管你重写与否,hashcode都有可能相同,你想想64位虚拟机有多少地址,hashcode是int值有多少个,很明显int无法覆盖内存地址啊
卖水果的net 2020-06-26
  • 打赏
  • 举报
回复

最简单的例子

    public static void main(String[] args) {
        Long x = -1L;
        Long y = 0L;
        System.out.println(x.hashCode());
        System.out.println(y.hashCode());
    }

卖水果的net 2020-06-26
  • 打赏
  • 举报
回复
又有人说:不同对象的hashCode可能一样。 这句话是对的。
SiegfriedG 2020-06-26
  • 打赏
  • 举报
回复
引用 1 楼 faith.huan 的回复:
答案肯定是可能相同的,如下s1,s2就不是同一对象,但他们有相同hashcode

String s1= new String("s");
String s2= new String("s");
System.out.println(s1 == s2);
System.out.println(s1.hashCode() == s2.hashCode());

我上来就说了【不重写hashCode的情况下】啊,String重写了hashCode和equals,用字符串内容做标准,肯定有这种情况。我问的是不重写,用原始Object内存地址来hash的情况。麻烦看清题目。
faith.huan 2020-06-26
  • 打赏
  • 举报
回复
64位能表示的地址数 2的64次方, int值是32位的,2的32次方. 所以无法覆盖啊, 这是理论值, 无法确定哪个地址与哪个地址的hash是一样的, 可以通过下面的代码简单测试下


package equals;

import java.util.HashSet;

/**
 * @author faith.huan 2020-06-26 15:25
 */
public class HashCodeTest {

    public static void main(String[] args) {

        HashSet<Integer> set = new HashSet<>();

        boolean flag = true;
        while (flag) {
            Object o = new Object();
            if (set.contains(o.hashCode())) {
                System.out.println("hashcode重复,setSize:" + set.size());
                flag = false;
            } else {
                set.add(o.hashCode());
            }
        }

    }
    
}

我的输出是 hashcode重复,setSize:105777
SiegfriedG 2020-06-26
  • 打赏
  • 举报
回复
引用 3 楼 faith.huan 的回复:
[quote=引用 2 楼 SiegfriedG的回复:][quote=引用 1 楼 faith.huan 的回复:]
答案肯定是可能相同的,如下s1,s2就不是同一对象,但他们有相同hashcode

String s1= new String("s");
String s2= new String("s");
System.out.println(s1 == s2);
System.out.println(s1.hashCode() == s2.hashCode());

我上来就说了【不重写hashCode的情况下】啊,String重写了hashCode和equals,用字符串内容做标准,肯定有这种情况。我问的是不重写,用原始Object内存地址来hash的情况。麻烦看清题目。[/quote]
不管你重写与否,hashcode都有可能相同,你想想64位虚拟机有多少地址,hashcode是int值有多少个,很明显int无法覆盖内存地址啊[/quote]


64位虚拟机有多少地址?

这个我不知道,刚搜了一下,一个对象大致要占100多byte不等的内存,以我电脑16G内存为例,算了一下,也就是10万级别的对象数量;而且项目中也有过相关经验,当创建几万个对象时,内存就爆了,怎么也达不到亿级别,和21亿相差甚远啊。
faith.huan 2020-06-26
  • 打赏
  • 举报
回复
答案肯定是可能相同的,如下s1,s2就不是同一对象,但他们有相同hashcode

String s1= new String("s");
String s2= new String("s");
System.out.println(s1 == s2);
System.out.println(s1.hashCode() == s2.hashCode());

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧