java 如何跟多个字符串比较_Stack Overflow上370万浏览量的一个问题:如何比较Java的字符串...
在逛 Stack Overflow 的時候,發(fā)現(xiàn)了一些訪問量像喜馬拉雅山一樣高的問題,比如說這個:如何比較 Java 的字符串?訪問量足足有 370萬+,這不得了啊!說明有很多很多的程序員被這個問題困擾過。
截止到目前為止,我一直使用“==”操作符來比較字符串,直到程序出現(xiàn)了一個 bug,需要使用 .equals() 方法來解決。這是為什么呢?“==”操作符和 .equals() 方法之間有什么區(qū)別呢?
和提問者相反,在我剛開始學(xué)習(xí) Java 的時候,比較字符串一直使用的是 .equals() 方法,因為不管是書本還是老師,都告誡我不要直接使用“==”操作符來比較,會出 bug。至于為什么,書本和老師都沒有幫我搞清楚。
那借此機會,我就來梳理一下 Stack Overflow 上的高贊答案,我們來一起學(xué)習(xí)進步,打怪升級。
- “==”操作符用于比較兩個引用(內(nèi)存中的存放地址)是否相等,它們是否是同一個對象。
- .equals() 用于比較兩個對象的內(nèi)容是否相等。
怎么理解這兩句話呢?我來舉個不恰當(dāng)又很恰當(dāng)?shù)睦印?/p>
有一對雙胞胎,姐姐叫阿麗塔,妹妹叫洛麗塔。我們普通人的眼睛完全無法分辨誰是姐姐誰是妹妹,可她們的媽媽卻可以輕而易舉地辨認(rèn)出。
.equals() 就好像我們普通人,看見阿麗塔以為是洛麗塔,看見洛麗塔以為是阿麗塔,看起來一樣就覺得她們是同一個人;“==”操作符就好像她們的媽媽,要求更嚴(yán)格,觀察更細致,一眼就能分辨出誰是姐姐誰是妹妹。
就上面這段代碼來說,.equals() 輸出的結(jié)果為 true,而“==”操作符輸出的結(jié)果為 false——前者沒后者要求那么嚴(yán)格。
大家都知道,Java 的所有類都默認(rèn)地繼承著 Object 這個超類,該類有一個名為 .equals() 的方法,源碼如下所示。
可以看得出,Object 類的 .equals() 方法默認(rèn)采用的是“==”操作符進行比較。假如子類沒有重寫該方法的話,那么“==”操作符和 .equals() 方法的功效就完全一樣——比較兩個對象的內(nèi)存地址或者對象的引用是否相等。
但實際情況中,有不少類重寫了 .equals() 方法,因為比較內(nèi)存地址太重了,不太符合現(xiàn)實的場景需求。String 類就重寫了 .equals() 方法,源碼如下所示。
可以看得出,如果兩個字符串對象“==”,那么 .equals() 的結(jié)果就為 true;否則的話,就比較兩個字符串的內(nèi)容是否相等。
大家應(yīng)該都知道了,創(chuàng)建字符串對象有兩種寫法,如下所示。
第一種是在字符串常量池(存儲在方法區(qū))中創(chuàng)建對象,并將對象的引用賦值給 luolita。第二種是通過 new 關(guān)鍵字在堆中創(chuàng)建對象,并將對象引用賦值給 alita。
PS:字符串作為最基礎(chǔ)的數(shù)據(jù)類型,使用非常頻繁,如果每次都通過 new 關(guān)鍵字進行創(chuàng)建,會耗費高昂的時間和空間代價。Java 虛擬機為了提高性能和減少內(nèi)存開銷,就設(shè)計了字符串常量池:相同字面量的對象只有一個。
PPS:Java 虛擬機在執(zhí)行程序的過程中會把內(nèi)存區(qū)域劃分為若干個不同的數(shù)據(jù)區(qū)域,如下圖所示。
下面我們通過實際代碼來看看字符串的比較。
第一種:
.equals() 比較的是兩個字符串對象的內(nèi)容是否相等,所以結(jié)果為 true。
第二種:
“==”操作符左側(cè)的對象存儲在堆中,右側(cè)的對象存儲在方法區(qū),所以返回 false。
第三種:
new 出來的兩個對象肯定是不相等的,所以返回 false。
第四種:
字符串常量池中只會有一個對象,所以返回 true。
由于“小”和“蘿莉”都在字符創(chuàng)常量池,所以編譯器會將其自動優(yōu)化為“小蘿莉”,所以返回 true。
經(jīng)過大量實例的分析,我們可以得出如下結(jié)論(也是對提問者的回答):
- 當(dāng)比較兩個字符串對象的內(nèi)容是否相等時,請使用 .equals() 方法。
- 當(dāng)比較兩個字符串對象是否相等時,請使用“==”操作符。
當(dāng)然了,如果要進行兩個字符串對象的內(nèi)容比較,除了 .equals() 方法,還有其他可選的方法。
1)Objects.equals()
Objects.equals() 這個靜態(tài)方法的優(yōu)勢在于不需要在調(diào)用之前判空。
如果直接使用 a.equals(b),則需要在調(diào)用之前對 a 進行判空,否則可能會拋出空指針 java.lang.NullPointerException。
2)String 類的 .contentEquals()
.contentEquals() 的優(yōu)勢在于可以將字符串與任何的字符序列(StringBuffer、StringBuilder、String、CharSequence)進行比較。
從源碼上可以看得出,如果 cs 是 StringBuffer,該方法還會進行同步,非常的智能化。不過需要注意的是,使用該方法之前,需要確保比較的兩個字符串都不為 null,否則將會拋出空指針。
再強調(diào)一點,.equals() 方法在比較的時候需要判 null,而“==”操作符則不需要。
總結(jié)
以上是生活随笔為你收集整理的java 如何跟多个字符串比较_Stack Overflow上370万浏览量的一个问题:如何比较Java的字符串...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java定义接口规范_关于java的接口
- 下一篇: centos mysql无法启动 soc