Java中的==和equals方法詳解,javaequals方法詳解
Java中的==和equals 1.如果比較對象是值變數:只用== 2.如果比較對象是引用型變數: ==:比較兩個引用是不是指向同一個對象執行個體。 equals: 首先Object類中equals的實現是直接調用了==操作。 一個自訂類繼承自Object且沒有重寫equals方法,那麼其equals操作也是與Object類一樣,僅僅是直接調用==操作。 如果一個類重寫過equals方法(或者繼承自一個重寫過equals方法的類),那麼效果與==操作不同 如果是你自己定義的一個類,比較自訂類用equals和==是一樣的,都是比較控制代碼地址, 因為自訂的類是繼承於object,而object中的equals就是用==來實現的。 檢查兩個引用型變數是否屬於同一個Class:instanceof System.out.println((obj1 instanceof Student) && (obj2 instanceof Student)) API裡的類大部分都重寫了equals方法。例如String類
1>String類型的比較: ==:比較兩個str是否是指向同一個對象執行個體。 equals:比較兩個str中的內容是否相同 對String的比較來說,還存在public String intern()方法。 當調用 intern 方法時,如果池已經包含一個等於此 String 對象的字串(該對象由 equals(Object) 方法確定),則返回池中的字串。否則,將此 String 對象添加到池中,並且返回此 String 對象的引用。 它遵循對於任何兩個字串 s 和 t,若且唯若 s.equals(t) 為 true 時,s.intern() == t.intern() 才為 true。
1 String a = new String("ab");2 String b = new String("ab");3 String c = "ab";4 String d = "a" + "b";5 String e = "b";6 String f = "a" + e;8 System.out.println(b.intern() == a);9 System.out.println(b.intern() == c);10 System.out.println(b.intern() == d);11 System.out.println(b.intern() == f);12 System.out.println(b.intern() == a.intern());
運行結果:false true true false true
由運行結果可以看出來,b.intern() == a和b.intern() == c可知
採用new 建立的字串對象不進入字串池,
字串相加的時候,都是靜態字串的結果會添加到字串池,如果其中含有變數(如f中的e)則不會進入字串池中。
在定義變數的時候賦值,如果賦值的是靜態字串,就會執行進入字串緩衝池的操作,如果池中含有該字串,則返回引用。
2>資料類型封裝類的比較
Java為每一個單一資料型別提供了一個封裝類,每個基礎資料型別 (Elementary Data Type)可以封裝成物件類型。 除int(Integer)和char(Character),其餘類型首字母大寫即成封裝類類型名。double (Double), float(Float),long(Long), short(Short),byte(Byte),boolean(Boolean).
以int和Integer為例說明 Java中int和Integer區別如下:
1.int是基本的資料類型,預設值可以為0;Integer是int的封裝類,預設值為null;
2.int和Integer都可以表示某一個數值,但int和Integer不能夠互用,因為他們兩種不同的資料類型;
int a1=1;
int a2=1;
Integer b1 =new Integer (1);
Integer b2 =new Integer (1);
Answer:
a1==a2 這個是成立的,很簡單,都知道
a1==b1 這個是不成立的.運算式的值為 false ,它們是不同的資料類型(在jdk1.5以上版本中為true)
b1==b2 這個也是不成立的.運算式的值為 false,雖然是相同的資料類型,但是它們是兩個對象,==比較的是2個對象的地址,它們的地址是不相等的,內容相等都是1;
b1.equals(b2)==true 這個是成立的,運算式的值為 true. 相同資料類型,兩個對象,地址不同,內容相同, quals比較的是2個對象的內容,所以成立。
(a.equals(b),因為equals比較的是兩個對象,所以a,b都不能為基礎資料型別 (Elementary Data Type),否則會出編譯錯誤。)(在jdk1.5以上版本中,b可以為基礎資料型別 (Elementary Data Type),a不可以) 同理,其它的封裝類和基本類型也是這樣
在jdk1.5以上的版本中,基本類型和封裝類能自動轉化,與String類型的對象和字串常量類似。
Integer i1 = 123; Integer i2 = 123; int i = 123; Integer i3 = new Integer(123); Integer i4 = new Integer(123); System.out.println("i1 == i2 = "+(i1 == i2)); System.out.println("i1.equals(i2) = "+(i1.equals(i2))); System.out.println(); System.out.println("i3 == i4 = "+(i3 == i4)); System.out.println("i3.equals(i4) = "+(i3.equals(i4))); System.out.println(); System.out.println("i2 == i4 = "+(i2 == i4)); System.out.println("i2.equals(i4) = "+(i2.equals(i4))); System.out.println(); System.out.println("i == i2 = "+(i == i2)); System.out.println("i1.equals(i) = "+(i1.equals(i))); System.out.println(); System.out.println("i == i4 = "+(i == i4)); System.out.println("i4.equals(i) = "+(i4.equals(i))); Answer: i1 == i2 = true i1.equals(i2) = true i3 == i4 = false i3.equals(i4) = true i2 == i4 = false i2.equals(i4) = true i == i2 = true i1.equals(i) = true i == i4 = true i4.equals(i) = true
3>對象的hashcode和equals 1)理解hashcode的作用 以java.lang.Object來理解,JVM每new一個Object,它都會將這個Object丟到一個Hash雜湊表中去。下次做Object的比較或者取這個對象的時候,它會根據對象的hashcode再從Hash表中取這個對象。這樣做的目的是提高取對象的效率。具體過程是這樣:
1.new Object(),JVM根據這個對象的Hashcode值,放入到對應的Hash表對應的Key上,如果發生了Hash key相同導致衝突的情況,那麼就在這個Hash key的地方產生一個鏈表,將所有產生相同hashcode的對象放到這個單鏈表上去。
2.比較兩個對象的時候,首先根據他們的hashcode去hash表中找他的對象,當兩個對象的hashcode相同,那麼就是說他們這兩個對象放在Hash表中的同一個key上,那麼他們一定在這個key上的鏈表上。那麼此時就只能根據Object的equal方法來比較這個對象是否equal。當兩個對象的hashcode不同的話,肯定他們不能equal.
兩個相等對象的equals方法一定為true, 但兩個hashcode相等的對象不一定是相等的對象。 2)覆蓋equals的時候總是要覆蓋hashcode 如果不覆蓋hashcode的時候,可能會出現這樣的情況,兩個對象覆蓋之後的equals方法返回為true,但其hashcode方法返回為false,而執行中的最佳化過程是,調用equals方法之前會先比較兩個對象的hash值,如果不同,就不會進行equals比較了。所以覆蓋equals方法而不覆蓋hashcode方法存在上述風險,比較本應該放回equals的true但是在預執行hash值比較時就返回了false。