Java中比較物件是否相同最常用的方式就是equals和'=='.很顯然這是不同的.
首先我們要了解一下JVM的基本構造.此處涉及到的主要是jvm的虛擬機器棧和堆heap..Java檔案經過編譯之後生成Class檔案.Class檔案透過類載入器Class Loader將資源放入JVM不同區域.棧區儲存物件引用地址和基本型別變數(int,boolean..),而堆區儲存具體物件資訊.
1.==首先.如果比較的是基本型別變數,直接比較棧區的值,很顯然相等
int a = 1int b = 1return a==b
如果比較的是包裝類,直接new一個物件,比較堆地址,不相等
Integer a = new Integer(1)Integer a2 = new Integer(1)
直接定義Integer物件時,編譯器會呼叫valueOf()自動裝箱(反編譯結果).當值在-128和127之外時,直接new一個物件.很顯然堆地址不同.
Integer a =1;low=-128 high=127public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i);}
而之內的範圍,翻譯一下就是首次使用的時候會初始化快取生成物件.堆地址已經固定了,自然-127-128之間的Integer可以直接比較.
其他的也類似可自行檢視.
/** * Cache to support the object identity semantics of autoboxing for values between * -128 and 127 (inclusive) as required by JLS. * * The cache is initialized on first usage. The size of the cache * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option. * During VM initialization, java.lang.Integer.IntegerCache.high property * may be set and saved in the private system properties in the * sun.misc.VM class. */
如果比較的是非基本變數,則比較他們的棧區所指向的堆地址.兩次String生成了兩個String類的例項,很顯然他們指向的堆地址是不一樣的.
String a ="1"; String b = "1";
2.equals
java.lang.Object是Java根類.如果一個類沒有指定父類,預設繼承Object類.比較堆指向地址.
public boolean equals(Object obj) { return (this == obj); }
當然,大部分類都重寫的equals方法.
demo:String.class
1.首先和自身比較肯定是true
2.instanceof判斷入參物件是否是String.class例項
3.比較字串長度是否相同
4.從字串頭部開始比較每一位是否相同
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;}
3.hashcodehashcode可以理解為一個加密演算法根據值得到一個密文來大致確定一個物件 .同一個物件的hashcode肯定相同但是雜湊碼相同的不一定是同一個物件.
hashcode主要運用在在雜湊如HashMap,HashSet中.
常用的資料結構如:
陣列,基於索引的有序資料結構,連續的記憶體空間,因此查詢很快.陣列初始化固定長度,陣列插入資料時,修改速度不盡人意.連結串列,基於指標,不連續記憶體空間,插入迅速,但是查詢緩慢.雜湊結合了陣列和列表.如果出現雜湊碰撞,在同一個位置使用連結串列或紅黑樹解決衝突.因此顯而易見,不能拿hashcode來判斷兩個物件是否相等.