1. 程式人生 > >==、equals()、hashcode()對比

==、equals()、hashcode()對比

結論:

1.     對於基本資料型別,==比較的是值,equals方法不能使用

2.     對於String和包裝類,==比較的是地址,equals方法比較的是值

3.     對於繼承Object的類,==比較的是地址,equals比較的也是地址

1.基本資料型別

==比較的是值

equals()是不能使用的(因為eauqls()是Object類的方法,物件才能呼叫)

例:

int a=100; 

int b=100; 

System.out.println("a=b"+(a==b));//true 

System.out.println("a.equals(b)"+a.equals.(b));//

編譯報錯

2.String和包裝類

==比較的是記憶體中存放的地址

equals()比較的是值,因為它們重寫了Object的equals()方法(類似還有Math,Date等值型別的類)

String部分

例如

String s1="hello"

String s2="hello";        

String s3=new String("hello"); 

String s4=new String("hello");   

String s5 = s3; 

String s6 = new String(s3);       

System.out.println("s1=s2"

+(s1==s2)); 

System.out.println("s1=hello"+(s1=="hello")); 

System.out.println("s3=s4"+(s3==s4)); 

System.out.println("s5=s3"+(s5==s3)); 

System.out.println("s3=s1"+(s3==s1)); 

System.out.println("s5=hello"+(s5 =="hello")); 

System.out.println("s6=hello"+(s6 =="hello")); 

System.out.println(s1.equals(s2)); 

System.out.println(s3.equals(s1)); 

System.out.println(s3.equals(s4)); 

輸出結果:

s1=s2 true

s1=hello true

s3=s4 false

s5=s3 true

s3=s1 false

s5=hello false

s6=hello false

true

true

true

是不是覺得一臉懵逼,摸不著頭腦?

看了下面string兩種賦值方法你一定會茅塞頓開

要知道String的兩種賦值方法:

① " "直接賦值法

② new關鍵字法

第一種直接賦值法Jvm會先去常量池中檢測該字串是否存在,若存在不建立直接地址指向,共享此字串,否則建立新的字串,類似Integer的自動裝箱,

第二種new建立的會直接在堆中開闢記憶體空間

所以s2和s1都指向常量池中hello字串

而s3和s4分別在中開闢了記憶體,分別指向不同地址

s3==s1前者記憶體為堆後者為常量池,自然有s3==s1為false

包裝類部分

注意Integer的享元模式:-128~127之間的數值在自動裝箱的過程中,如果記憶體中存在相同數值的Integer類物件,則會共享此物件

看完下面的部分你就會明白

首先要知道包裝類的自動裝箱和自動拆箱機制

大家一定都見過這個語句Integer i= 5;

在jdk1.5以前,這樣的程式碼是錯誤的,必須要通過Integeri = newInteger(5);這樣的語句實現;而在jdk1.5以後,Java提供了自動裝箱的功能,只需Integer i= 5; JVM會幫我們自動裝箱,即基本資料型別轉為包裝類

相應的,包裝類到基本資料型別的過程就是拆箱;如

Integeri =5

intj =i;//自動拆箱

底層原始碼:

裝箱過程是通過呼叫包裝器的valueOf方法實現的,而拆箱過程是通過呼叫包裝器的xxxValue方法實現的。(xxx代表對應的基本資料型別)

注意:

Integer i=new Integer(xxx) 不會觸發自動裝箱的過程

Integeri=xxx;才會觸發;

例如

Integer i1= new Integer(100);//手動裝箱

Integer i2= newInteger(100); 

System.out.println("i1=i2" + (i1 == i2));//false 

System.out.println("i1.equals(i2)"+i1.equals(i2));//true 

符合我們的預期,因為i1和i2是不同的物件不同的地址

Integer i1= 200;//自動裝箱

Integer i2= 200; 

System.out.println("i1=i2" + (i1 ==i2));//false 

符合我們的預期,因為i1和i2是不同的物件不同的地址

Integer i1= 100; 

Integer i2= 100; 

System.out.println("i1=i2" + (i1 ==i2));//true 

好奇怪?換個數值結果竟然不一樣?難道i1和i2是同一個物件嗎?

結論:此時的i1和i2指向同一物件,原因是Integer比較特殊,在自動裝箱過程中,對於-128~127的值,它們被裝箱為Integer物件後,會存在記憶體中被重用,始終只存在一個物件,而如果超過-128~127的值,被裝箱後的Integer物件並不會被重用,相當於new一個新的Integer物件

另外包裝類==基本資料型別 比較的也是值

Integer i1= 200; 

Integer i2= 100; 

Integer i3= i2+100;//結果300不在-128~127,自動裝箱時產生新的物件

System.out.println("i1=i2+i0" + (i1 == i3));//false 

int i=200; 

System.out.println("i1=i"+(i1==i));//true 

System.out.println("i1=i2+100"+(i1==i2+100));//true 

因為i2+100運算完得到200,還沒有來得及自動裝箱就和i1進行了比較

包裝類例:

Integer i1= newInteger(100); 

Integer i2= newInteger(100); 

Integer i3= 200; 

Integer i4= 200; 

Integer i5= 100; 

Integer i6= 100; 

System.out.println(i1.equals(i2)); 

System.out.println("i1=i2" + (i1 == i2)); 

System.out.println("i3=i4" + (i3 == i4)); 

System.out.println("i5=i6" + (i5 == i6)); 

System.out.println("i5=i6+0"+(i5==i6+0)); 

輸出結果:

true

i1=i2 false

i3=i4 false

i5=i6 true

i5=i6+0 true

3.繼承Object的類

== 比較的是地址

equals()比較的是地址,沒有重寫Object類中的equals(),比較兩個物件的引用是否相等

例如

Object obj1=new Object();

Object obj2=new Object();

System.out.println(obj1==obj2);

System.out.println(obj1.equals(obj2));

StringBuffer s1=new StringBuffer();

StringBuffer s2=new StringBuffer();

System.out.println(s1==s2);

System.out.println(s1.equals(s2));

輸出結果:

false

false

false

false

equals()和hashcode ()的比較:

當比較大量資料的時候hashcode()比equals()效率高

比如向hashset(不允許重複)集合中有1000個元素,新增新元素的時候

equals:呼叫這個元素的equals()方法,遍歷所有元素依次對比,沒有重複的話新增

hashcode:呼叫這個元素的hashcode()方法,定位到相映的物理位置上

如果沒有元素,它就可以直接儲存在這個位置上,不用再進行任何比較

如果已經有元素了,就呼叫equals方法與新元素進行比較,相同則不存,不相同的話,也就是發生了Hash key相同導致衝突的情況,那麼就在這個Hash key的地方產生一個連結串列,將這些元素串在一起

equal()相等的兩個物件他們的hashCode()肯定相等

hashCode()相等的兩個物件他們的equal()不一定相等,因為可能會發生Hash雜湊值衝突

所以當有大量元素需要進行比較的時候先用hashcode()比較,不相等則兩個元素不等。如果hashcode()相等,再呼叫equals()比較,如果equal()也相同,則表示這兩個元素相同。

相關推薦

==equals()hashcode()對比

結論: 1.     對於基本資料型別,==比較的是值,equals方法不能使用 2.     對於String和包裝類,==比較的是地址,equals方法比較的是值 3.     對於繼承Object的類,==比較的是地址,equals比較的也是地址 1.基本資料型別

==equals()hashcode()的關係和區別

==、equals()、hashcode()概念 ==:它的作用是判斷兩個物件的地址是不是相等。即,判斷兩個物件是不試同一個物件。 equals():它的作用也是判斷兩個物件是否相等。但它一般有兩種使用情況:   情況1,類沒有覆蓋equals()方法。則通過equals()比較該類的兩個物件時,等價於

Java String引起的常量池String類型傳參“==”equalshashCode”問題 細節分析

怎麽辦 理解 amp 標準 col 要求 oid font 說明   在學習javase的過程中,總是會遇到關於String的各種細節問題,而這些問題往往會出現在Java攻城獅面試中,今天想寫一篇隨筆,簡單記錄下我的一些想法。話不多說,直接進入正題。 1.String常量池

淺談Java中物件的==equalshashCode

目錄 運算子 == equals() String中的equals() Integer中的equals() Long中equals() hashCode() 運算子 == Java中的==是比較兩

"=="equalshashCode有什麼區別

1)“==”運算子用來比較兩個變數的值是否相等。也就是說,該運算子用於比較變數對應的記憶體中所儲存的數值是否相同,要比較兩個基本型別的資料或兩個引用變數是否相等,只能使用“==”運算子。 具體而言,如果兩個變數是基本資料型別,可以直接使用“==”運算子來比較其對應的值是否相

==equalshashcode的區別和聯絡

一、equals和==的區別 java中的資料型別,可分為兩類: 1.基本資料型別,也稱原始資料型別。byte,short,char,int,long,float,double,boolean   

Java中==equalshashcode的區別與重寫equals以及hashcode方法例項

  1、重寫equals方法例項   部分程式碼參考http://blog.csdn.net/wangloveall/article/details/7899948   重寫equals方法的目的是判斷兩個物件的內容(內容可以有很多,比如同時比較姓名和年齡,同時相同的才是用一個物件)是否相同 如果不重寫e

【JAVA學習】java中==equals()hashCode()都和物件的比較有關,在java中這三者各有什麼用處呢,即java中為什麼需要設計這三種物件的比較方法呢?

關於hashCode() 為什麼會設計hashCode()方法?    hashCode()方法返回的就是一個數值,我們稱之為hashCode吧。從方法的名稱上就可以看出,其目的是生成一個hash碼。hash碼的主要用途就是在對物件進行雜湊的時候作為key輸入,據此很容易推斷出,我們需要每個物件的ha

scala的==equalseqne區別與用法

根據官方API的定義: final def ==(arg0: Any): Boolean The expression x == that is equivalent to if (x eq null) that eq null else x.equals(that) final de

Java:比較運算子compareTo()equals()==之間的區別與應用總結

1、== 和 equals的區別:  ==主要是兩個變數值的比較,返回值為true 或者是false。對於普通變數,如:int a=10; int  b= 10; a==b,返回為 true。 而對於下面情況: String  a=new S

【轉】java ==equalscompareTocomparesort在比較上的應用

        兩個方法的返回值都是int型,結果有大於、小於、等於三種值,用於給資料排序,負數表示小於、0表示相等、正數表示大於。        集合工具類 Collections類中的sort方法是用於對集合進行排序。Collections類中名稱為sort的方法有兩個,其中一個呼叫的是comparaTo

Java:驗證在類繼承過程中equals() hashcode()toString()方法的使用

red ger 輸出 ria oid nag println manage base 以下通過實際例子對類創建過程匯中常用的equals()、hashcode()、toString()方法進行展示,三個方法的創建過程具有通用性,在項目中可直接改寫。 //通過超類Employ

【轉載】hashCode()equals()以及compareTo()方法的理解

進行 一個 terms 兩個 定義 == bject str rac 判斷兩個對象是否相等(是同一個對象),首先調用hashCode()方法得到各自的hashcode, 1、如果hashcode不相等,則表明兩個對象不相等。 2、如果hashcode相等,繼續調用equal

hashcode()和equals()的作用區別聯系

ces 引用 val 流程圖 依據 highlight key 基本類 util 介紹一、 hashCode()方法和equal()方法的作用其實一樣,在Java裏都是用來對比兩個對象是否相等一致,那麽equal()既然已經能實現對比的功能了,為什麽還要

equalsHashCode與實體類的設計

public 相同 不用 java 元素 avi 沒有 設計 sta equals和HashCode都是用來去重的,即判斷兩個對象是否相等。如果是String類則我們直接用.equals()判斷,如果是我們自己定義的類,需要有自己的判斷方

List集合去重的一些方法(常規遍歷Set去重java8 stream去重重寫equalshashCode方法)

利用 src false java8 see eat 基本 style ceo 1. 常規元素去重 碰到List去重的問題,除了遍歷去重,我們常常想到利用Set集合不允許重復元素的特點,通過List和Set互轉,來去掉重復元素。 // 遍歷後判斷賦給另一個list集

MapReduce關於key的定義hashCode()equals(Object obj)compareTo(CustomCombineKey other)

1. mapreduce中自定義mapout、reduceinput的key key需實現WritableComparable<KEY> 介面 1.1 重寫下面的三個方法 1.2 重寫

淺談---對equalshashCode“==”的理解

在我們平常的學習中,經常會涉及到equals、hashCode、“==”這三者,對於這三者我經常混淆不清。因此,我自行總結了一下。 先說下在我們程式設計中用到的比較不容易區分的equals和hashCode的區別 equals和hashCode都是Object類

Java 011 Object類的常用方法(hashCodetoStringgetClassequals

知識點梳理 心得體會 小知識點 1.若呼叫toString()輸出的不是地址值,則toString()一定被重寫了 2.instanceof是一個二元操作符(運算子),用來判斷,instanceof 左邊物件是否為instanceof 右邊類的例項,返回一個b

java程式碼優化(二)——如何覆蓋Object的公用方法(equalshashcodecompareTotoString)

覆蓋equals方法時請遵守通用約定 什麼情況需要覆蓋equals方法? 當需要比較的類有自己的邏輯特點時,而Object的equals方法不能達到預期的效果時,就需要覆蓋equals比較類的屬性值。 覆蓋equals方法的通用約定 自反性——對於任何非null的物件