(面试题)两个对象值相同 (x.equals(y) == true) ,但却可有不同的 hash code ,这 句话对不对

(面试题)两个对象值相同 (x.equals(y) == true) ,但却可有不同的 hash code ,这 句话对不对
答:不对,有相同的 hash code
这是java语言的定义:

  1. 对象相等则hashCode一定相等;
  2. hashCode相等对象未必相等

1.如果是基本变量,没有hashcode和equals方法,基本变量的比较方式就只有==;

2.如果是变量,由于在java中所有变量定义都是一个指向实际存储的一个句柄(你可以理解为c++中的指针),在这里==是比较句柄的地址(你可以理解为指针的存储地址),而不是句柄指向的实际内存中的内容,如果要比较实际内存中的内容,那就要用equals方法,但是!!!

如果是你自己定义的一个类,比较自定义类用equals和是一样的,都是比较句柄地址,因为自定义的类是继承于object,而object中的equals就是用来实现的,你可以看源码。

那为什么我们用的String等等类型equals是比较实际内容呢,是因为String等常用类已经重写了object中的equals方法,让equals来比较实际内容,你也可以看源码。

  1. hashcode

在一般的应用中你不需要了解hashcode的用法,但当你用到hashmap,hashset等集合类时要注意下hashcode。

你想通过一个object的key来拿hashmap的value,hashmap的工作方法是,通过你传入的object的hashcode在内存中找地址,当找到这个地址后再通过equals方法来比较这个地址中的内容是否和你原来放进去的一样,一样就取出value。

所以这里要匹配2部分,hashcode和equals

但假如说你new一个object作为key去拿value是永远得不到结果的,因为每次new一个object,这个object的hashcode是永远不同的,所以我们要重写hashcode,你可以令你的hashcode是object中的一个恒量,这样永远可以通过你的object的hashcode来找到key的地址,然后你要重写你的equals方法,使内存中的内容也相等。。。

一般来讲,equals这个方法是给用户调用的,如果你想判断2个对象是否相等,你可以重写equals方法,然后在代码中调用,就可以判断他们是否相等了。简单来讲,equals方法主要是用来判断从表面上看或者从内容上看,2个对象是不是相等。举个例子,有个学生类,属性只有姓名和性别,那么我们可以认为只要姓名和性别相等,那么就说这2个对象是相等的。

hashcode方法一般用户不会去调用,比如在hashmap中,由于key是不可以重复的,他在判断key是不是重复的时候就判断了hashcode这个方法,而且也用到了equals方法。这里不可以重复是说equals和hashcode只要有一个不等就可以了!所以简单来讲,hashcode相当于是一个对象的编码,就好像文件中的md5,他和equals不同就在于他返回的是int型的,比较起来不直观。我们一般在覆盖equals的同时也要覆盖hashcode,让他们的逻辑一致。举个例子,还是刚刚的例子,如果姓名和性别相等就算2个对象相等的话,那么hashcode的方法也要返回姓名的hashcode值加上性别的hashcode值,这样从逻辑上,他们就一致了。

要从物理上判断2个对象是否相等,用==就可以了
分类: 面试题
好文要顶 关注我 收藏该文
嗨,你的益达~~~
关注 - 16
粉丝 - 62
+加关注
0 0
« 上一篇:有关java调用方法参数传递的分析
» 下一篇:【转】java io 流 设计模式
posted @ 2013-08-08 16:16 嗨,你的益达~~~ 阅读(14102) 评论(6) 编辑 收藏

评论列表
#1楼 2014-11-14 11:21 whzhaochao
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.test;

public class Main {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Test x=new Test("x");
    Test y=new Test("y");
    System.out.println("x HashCode="+x.hashCode());
    System.out.println("y HashCode="+y.hashCode());
    System.out.println(x.equals(y)==true);
}

}

class Test{
private String name;
public Test(String name){
this.name=name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
    return true;
}

}

结果
1
2
3
x HashCode=151
y HashCode=152
true
支持(0)反对(2)
#2楼 2015-09-04 11:51 树根根
@ whzhaochao
真逗,你重写的equal就是个圈套,比都不比,直接return true; ,你在豁楼主吗?
支持(1)反对(2)
#3楼 2015-09-16 13:04 popezong
@ 树根根
你这。。仔细看好了 上面那个人是对的。楼主自己理解不对
支持(0)反对(0)
#4楼 2016-10-12 10:48 LytZz
hashCode 的常规协定是:

1.在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
2.如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
3.如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。

实现方法如下:
该需求就要重写euqals方法,并且不能重写hashcode方法,并使用hashset实现。把所有的超人放到一个hashset中去,循环遍历set,调用change方法,通知变身,这就是所谓的观察者模式。
当使用观察者模式时,即使观察的对象重写了equals方法,使用了Hashset,也必须不能重写hashcode方法,否则会有对象观测不到通知
支持(0)反对(0)
#6楼 2018-04-21 13:57 梦幻怪兽
hashcode和equals具体是否同步,没有规定,JVM只是说明使用集合的时候需要考虑这两个同步性的问题。同步与不同步,最终会有两种不同现象,具体那种是你需要的,无人知晓,所以不能一概而论
如果需要深入理解hashcode和equals,可以看这里
https://blog.csdn.net/menghuanguaishou/article/details/80025647

· 两个对象值相同(x.equals(y)==true),但却可有不同的hashcode这句话对吗?
· 两个对象值同样(x.equals(y) == true),但却可有不同的hash code,这句话对不正确?
· 【Java面试题】41 两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
· 两个对象用equals方法比较为true,它们的Hashcode值相同吗?
· 两个对象值相同,有相同的hash code

猜你喜欢

转载自blog.csdn.net/weixin_42595331/article/details/85239698