1. 程式人生 > >JAVA基礎--java中equals,hashcode和==的區別

JAVA基礎--java中equals,hashcode和==的區別

1、==
在談JAVA中使用 == 前首先要明白Java中的資料型別分為兩種,即基本資料型別和引用資料型別,在該兩種情況下使用 所代表的含義也是不同。
基本資料型別:
Java中的基本資料型別包括四類八種,即
布林型:boolean(1/8Byte);
字元型:char(2 Byte 一個字元可儲存一個漢字);
整形:byte(1Byte) ,short (2Byte),int (4Byte), long (8Byte);
浮點型:float (4Byte),double (8Byte);
在基本資料型別中使用 == 表示的值之間的比較,返回的是boolean型別,例如

int a = 3;
char c = 'a';
System.out.println(a==c);

這裡需要注意char中字元對應的是ASCII碼值,其中’a’代表97,'A’代表65,例如:

int a = 97;
char c = 'a';
System.out.println(a==c);

輸出結果則為true;

引用資料型別
在解釋引用資料型別之前首先要明白兩個概念,即棧和堆。
:執行先進後出,主要儲存方法的區域性變數,每個方法都會分配一塊記憶體空間,方法一旦執行完成,就會將該空間釋放;
:執行先進先出,主要儲存陣列和物件(即通過new出來的),因此堆中儲存的都是實體。
例如執行如下語句:

Integer aInteger  = new Integer(3);

JVM在載入該語句所在的方法時,首先會在棧中定義一個變數aInteger ,然後在堆中分配一個記憶體地址來儲存右邊的實體,該實體儲存的值是3,比如記憶體地址是0x001,最後將該地址賦給aInteger,這樣aInteger 就引用了堆中的實體,也就是棧中儲存的是地址值, 堆中儲存的是實體值,當該語句所在的方法銷燬後,該棧中的aInteger 也隨之銷燬,堆中的實體雖然不會馬上銷燬,但當JVM檢測到該實體不存在被引用時,也會主動將其銷燬,至此就完成了一個呼叫過程。
以上主要是想說明在引用資料型別使用 ==時,比較的是棧中的地址值,而不是堆中的實體值,比如:

Integer aInteger  = new Integer(3);
Integer bInteger  = new Integer(3);
System.out.println(aInteger == bInteger);

結果輸出的為:false
除非將該地址的引用賦值給棧中的另一個變數,例如:

Integer aInteger  = new Integer(3);
Integer integer = new Integer(4);
integer = aInteger;
System.out.println(integer == aInteger);

剛開始aInteger 和integer 所指向堆中的實體值不同,當然其獲取的地址值也不同,但由於aInteger將其地址值賦給integer,因此aInteger和integer同時指向了同一個堆中實體,此時如果輸出integer的值則為3而不是4。

2 、equals
equals用於引用資料型別,不適於基本資料型別,在呼叫equlas時,預設呼叫的是object中的equlas中的方法:

public boolean equals(Object obj) {
        return (this == obj);
    }

而Object中的equals是判斷棧中記憶體的地址值,因此在自定義引用資料型別時,需要重寫equals方法,根據需求改寫,例如:

	@Override
	public boolean equals(Object obj) {
		if(this ==obj) {
			return true;
		}else {
			return false;
		}
	}

通過自定義修改equals的方法是根據需求改寫,而Java中基本的引用資料型別也是重寫equals方法,例如Integer:

 public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

首先檢視該物件是不是其型別(instanceof ),如果不是直接返回false,然後獲取其實體值,因此其比較的則是堆中的實體值,而不是棧中的地址值。