==, equals 与 hashCode 的区别与联系

概述

概念:
== : 该操作符生成的是一个boolean结果,它计算操作数值之间的关系。
equals : Object 的实例方法,比较两个对象的内容是否相同。
hashCode : Object的native方法 , 获取对象的哈希值,用于确定该对象在哈希表中的索引位置,它实际上是一个int型整数(哈希表就是散列表,根据(key,value)直接进行数据访问,native关键字暗示这些方法是有实现体的,只不过这些实现体是非java的,但不能和abstract连用)

==
1、不同数据类型
a.基本数据类型变量
在Java中有八种基本数据类型:
浮点型:float(4 byte), double(8 byte)
整型:byte(1 byte), short(2 byte), int(4 byte) , long(8 byte)
字符型: char(2 byte)
布尔型: boolean(JVM规范没有明确规定其所占的空间大小,仅规定其只能够取字面值”true”和”false”)
变量直接存储这八种基本数据类型的“值”。
所有**==**直接比较的值本身。
b.引用类型变量(数组,类,接口)
在Java中,引用类型的变量存储的并不是“值”本身,而是与其关联的对象在内存中的地址。

比如下面句话声明了一个引用类型的变量,此时它并没有和任何对象关联。
而通过 new 来产生一个对象,并将这个对象和str1进行绑定:

String str1;
str1 = new String("hello");

那么 str1 就指向了这个对象,此时引用变量str1中存储的是它指向的对象在内存中的存储地址,并不是“值”本身,也就是说并不是直接存储的字符串”hello”。这里面的引用和 C/C++ 中的指针很类似。

小结
因此,对于关系操作符 ==:
若操作数的类型是基本数据类型,则该关系操作符判断的是左右两边操作数的值是否相等
若操作数的类型是引用数据类型,则该关系操作符判断的是左右两边操作数的内存地址是否相同。如果返回true,则说明是同一个对象。

equals
初学Java的时,很多人认为: ==是比较地址,equals()是比较对象的内容,
但equals()方法在Object类中的定义:

public boolean equals(Object obj){
  return (this==obj);//这是在比较指针地址
}

说equals是比较内容,是因为在String、Double等封装类中,已经重载(overriding)了Object类的equals()方法,是进行内容的比较。
比如在String类中:

public int hashCode(){
  int h = hash;
  if(h == 0){
    char len = count;
    for(int i-0;i<len;i++){
      h = 31*h + val[off++];
    }
    hash = h
  }
  return h;
}

hashCode
在Object类中的定义为:

public native int hashCode();

hashCode()是一个 native方法,返回的对象的地址值。
但是,同样的思路,在String等封装类中对此方法进行了重写。方法调用得到一个计算公式得到的 int 值.

hashCode和equlas的关系
1、如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同
2、如果两个对象的hashCode相同,它们equals并不一定相同;
原因:从散列的角度考虑,不同的对象计算哈希码的时候,可能引起冲突。(哈希码代表对象的特征,是一种算法,不同对象的哈希码可能相同也可能不同)

  • 在数据结构中为了提高程序的效率才实现了hashcode方法,先进行hashcode的比较,如果不同,那没就不必在进行equals的比较了,这样就大大减少了equals比较的次数,这对比需要比较的数量很大的效率提高是很明显的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值