java中的==、equals()、hashCode()源码剖析 (转)ITeye - AG环亚娱乐集团

java中的==、equals()、hashCode()源码剖析 (转)ITeye

2019年03月13日15时05分31秒 | 作者: 炫明 | 标签: 目标,源码,办法 | 浏览: 1729

转自:http://www.cnblogs.com/xudong-bupt/p/3960177.html


在java编程或许面试中经常会遇到 、equals()的比较。自己看了看源码,结合实际的编程总结一下。

1.

java中的是比较两个目标在JVM中的地址。比较好了解。看下面的代码:
public class ComAddr{
 public static void main(String[] args) throws Exception {
 String s1 = "nihao";
 String s2 = "nihao";
 String s3 = new String("nihao");
 System.out.println(s1  s2); // true
 System.out.println(s1  s3); // false

上述代码中:

(1)s1 s2为true,是由于s1和s2都是字符串字面值"nihao"的引证,指向同一块地址,所以持平。

(2)s1 s3为false,是由于经过new发生的目标在堆中,s3是堆中变量的引证,而是s1是指向字符串字面值"nihao"的引证,地址不同所以不持平。

2.equals()

equals是根类Obeject中的办法。源代码如下:
public boolean equals(Object obj) {
 return (this  obj);
}

可见默许的equals办法,直接调用,比较目标地址。

不同的子类,能够重写此办法,进行两个目标的equals的判别。

String类源码中重写的equals办法如下,
public boolean equals(Object anObject) {
 if (this  anObject) {
 return true;
 if (anObject instanceof String) {
 String anotherString = (String) anObject;
 int n = value.length;
 if (n  anotherString.value.length) {
 char v1[] = value;
 char v2[] = anotherString.value;
 int i = 0;
 while (n != 0) {
 if (v1[i] != v2[i])
 return false;
 i++;
 return true;
 return false;
 }

从上面的代码中能够看到,

(1)String类中的equals首要比较地址,假如是同一个目标的引证,可知目标持平,回来true。

(2)若果不是同一个目标,equals办法挨个比较两个字符串目标内的字符,只要彻底持平才回来true,不然回来false。
3.hashcode()

hashCode是根类Obeject中的办法。

默许情况下,Object中的hashCode() 回来目标的32位jvm内存地址。也就是说假如目标不重写该办法,则回来相应目标的32为JVM内存地址。

String类源码中重写的hashCode办法如下,

public int hashCode() {
 int h = hash; //Default to 0 # String类中的私有变量,
 if (h  0 value.length 0) { //private final char value[]; # Sting类中保存的字符串内容的的数组
 char val[] = value;
 for (int i = 0; i value.length; i++) {
 h = 31 * h + val[i];
 hash = h;
 return h;
}

String源码中运用private final char value[];保存字符串内容,因而String是不可变的。

看下面的比如,没有重写hashCode办法的类,直接回来32位目标在JVM中的地址;Long类重写了hashCode办法,回来计算出的hashCode数值:
public class ComHashcode{
 public static void main(String[] args) throws Exception {
 ComHashcode a = new ComHashcode();
 ComHashcode b = new ComHashcode();
 System.out.println(a.hashCode()); //870919696
 System.out.println(b.hashCode()); //298792720
 Long num1 = new Long(8);
 Long num2 = new Long(8);
 System.out.println(num1.hashCode()); //8
 System.out.println(num2.hashCode()); //8
}

总结:

(1)绑定。当equals办法被重写时,一般有必要重写 hashCode 办法,以保护 hashCode 办法的惯例协议,该协议声明持平目标有必要具有持平的哈希码。

(2)绑定原因。Hashtable完成一个哈希表,为了成功地在哈希表中存储和检索目标,用作键的目标有必要完成 hashCode 办法和 equals 办法。同(1),有必要确保equals持平的目标,hashCode 也持平。由于哈希表经过hashCode检索目标。

(3)默许。

默许比较目标在JVM中的地址。

hashCode 默许回来目标在JVM中的存储地址。

equal比较目标,默许也是比较目标在JVM中的地址,同



参阅:

http://docs.oracle.com/javase/7/docs/api/
版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表AG环亚娱乐集团立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章