equals与hashcode

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

不对,有相同的 hash code 。首先 equals() hashcode() 这两个方法都是从 object 类中继承过来的。

equals() 方法在 object 类中定义如下:

public boolean equals(Object obj) {

return (this == obj);

}

很明显是对两个对象的地址值进行的比较(即比较引用是否相同)。但是我们必需清楚,当 String Math 、还有 Integer Double 。。。。等这些封装类在使用 equals() 方法时,已经覆盖了 object 类的 equals ()方法。 是进行的内容比较,而已经不再是地址的比较。依次类推 Double Integer Math 。。。。等等这些类都是重写了 equals() 方法的,从而进行的是内容的比较 。当然了基本类型是进行值的比较 ,这个没有什么好说的。

我们还应该注意, Java 语言对 equals() 的要求如下,这些要求是必须遵循的:

对称性 :如果 x.equals(y) 返回是“ true ”,那么 y.equals(x) 也应该返回是“ true ”。

反射性 x.equals(x) 必须返回是“ true ”。

类推性 :如果 x.equals(y) 返回是“ true ”,而且 y.equals(z) 返回是“ true ”,那么 z.equals(x) 也应该返回是“ true ”。

还有一致性 :如果 x.equals(y) 返回是“ true ”,只要 x y 内容一直不变,不管你重复 x.equals(y) 多少次,返回都是“ true ”。

任何情况下, x.equals(null) ,永远返回是“ false ”; x.equals( x 不同类型的对象 ) 永远返回是“ false ”。

以上这五点是重写 equals() 方法时,必须遵守的准则,如果违反会出现意想不到的结果,请大家一定要遵守。

2. 其次是 hashcode() 方法,在 object 类中定义如下:

public native int hashCode();

说明是一个本地方法,它的实现是根据本地机器相关的。当然我们可以在自己写的类中覆盖 hashcode() 方法,比如 String Integer Double 。。。。等等这些类都是覆盖了 hashcode() 方法的。

想要明白 hashCode 的作用,你必须要先知道 Java 中的集合。总的来说, Java 中的集合( Collection )有两类,一类是 List ,再有一类是 Set 。前者集合内的元素是有序的,元素可以重复;后者元素无序,但元素不可重复。那么这里就有一个比较严重的问题了:要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢?这就是 Object.equals 方法了。但是,如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。也就是说,如果集合中现在已经有 1000 个元素,那么第 1001 个元素加入集合时,它就要调用 1000 equals 方法。这显然会大大降低效率 。于是, Java 采用了哈希表的原理。 hashCode 方法实际上返回的就是对象存储的物理地址(实际可能并不是) 。这样一来,当集合要添加新的元素时,先调用这个元素的 hashCode 方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了。所以这里存在一个冲突解决的问题。这样一来实际调用 equals 方法的次数就大大降低了,几乎只需要一两次。   

3. 这里我们首先要明白一个问题:

equals() 相等的两个对象, hashcode() 一定相等; hashcode() 不等,一定能推出 equals() 也不等 hashcode() 相等, equals() 可能相等,也可能不等。

equals() 方法会自动调用 hashCode 方法么?不会 . 除非你设计一个 equals() 方法 让它调用 hashCode() 方法 . HashSet 里的 add() 方法会通过一系列的调用使用到 hashCode() 方法 , 因为它要根据 hash 值来确定存储位置 , 不是 equals 方法调用的 . 凡是用哈希表实现的集合先比较的是 hashCode 方法,这是为了程序性能的问题。

  当一个对象你只重写 equals 方法或 hashCode 方法,那么势必在一种情况下成立一种情况下不成立,所以只有 2 个方法同时改的情况下就会在各种情况下都出现你要的结果。 我想这就是重写 equals() 方法必须重写 hashCode 方法的原因!

hashcode() 的函数,如果写成 return 1; 行不行。

我说是可以的,只是性能很差 ,不停的冲突。看得出来这个回答还是让他很满意的。 hashCode() 返回该对象的哈希码值,该值通常是一个由该对象的内部地址转换而来的整数,它的实现主要是为了提高哈希表 ( 例如 java.util.Hashtable 提供的哈希表 ) 的性能。哈希函数,解决冲突。

 equals() 与“ ==

"==" 比较的是两个对象的引用 (references) ,并不是他们的内容 , (只是针对于对象类型,基本类型直接使用 == 或! = 比较内容)

Object 中的 equals(Object) 方法其标准形式为     public boolean equals(Object obj) ;返回类型为 boolean ,即 true/false "==" 返回类型一样。 Object 类中定义的 equals(Object) 方法是直接使用 "==" 比较的两个对象 ,所以在没有覆盖 (override ,或称改写、重写 ) equals(Object) 方法的情况下, equals(Object) "==" 一样是比较的引用

equals(Object) 方法与 "==" 相比的特殊之处就在于它可以覆盖 ,所以我们可以通过覆盖的办法让它不是比较引用而是比较数据内容 。当然 JDK 中也有覆盖过 equals(Object) 方法的类,如 java.lang.String ,它就覆盖了从 Object 继承来的的 equals(Object) 方法,用以比较字符串内容是否相同 。看看下面这个例子:

    public class Example1    {
    public static void main(String[] args){
    String s1=new String("abc");
    String s2=new String("abc");
    System.out.println("
== 比较结果 ");
    System.out.println(s1==s2);
//false
    System.out.println("
equals(Object) 比较结果 ");
    System.out.println(s1.equals(s2));
//true
    }
    }
   
例中用 equals(Object) 比较结果为 true 。用 == 比较结果为 false String.equals(Object) 方法直接比较了两个字符串的内容 ,如果相同则返回 true ,否则返回 false

由于和对象相关的变量属于引用类型,使用 obj1 obj2 obj1 只是得到一份 obj2 应用的副本,而不是 obj2 对象本身。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值