而這個替換表達式的計算結果爲真,爲什麼下面的表達式計算爲假爲什麼Java的String#replace()方法對字符和字符串的工作方式不同?
aStr.replace("H", "H") == "Hello"
?
aStr.replace('H', 'H') == "Hello"
而這個替換表達式的計算結果爲真,爲什麼下面的表達式計算爲假爲什麼Java的String#replace()方法對字符和字符串的工作方式不同?
aStr.replace("H", "H") == "Hello"
?
aStr.replace('H', 'H') == "Hello"
字符串比較應使用.equals()
如果比較字符串字面之間完成,然後==比較可能的工作,因爲文字在池中緩存,並參考同一個變量。
equals()
比較值,==
比較參考。
的Java緩存String
文字的字符串池,所以如果在String
沒有改變它會從池中的基準收益採取一成不變的實例,這樣既指的是同一個實例在內存中,因此==
true
所以比較String對象,你應該使用equals()
方法/ compareTo()
方法
請參見
使用String.equals()比較字符串。
System.out.println((aStr.replace("H","H").equals("Hello")));
將返回真正。
String
類的replace(char, char)
方法掃描尋找匹配的字符。如果沒有找到它,它將按原樣返回主機String
。自然地,通過==
運算符將返回的引用與原始引用進行比較返回true,因爲這是測試引用相等,並且這兩個引用是同一個。
但是,如果原始字符串包含了一個「H」字—使用你的例子這裏—那麼返回的字符串將不是一樣的原始字符串(儘管這將是相同的字符逐字符);它將是一個新分配的實例,它將通過引用等式進行比較失敗(同樣,==
運算符)。將返回的String
與原始通過Object#equals()
進行比較將返回true,因爲這兩個字符串是等效於,但它們將是通過引用相等無法匹配的不同實例。
相比之下,String#replace(CharSequence, CharSequence)
將目標字符串視爲正則表達式;它在內部使用Matcher#replaceAll()
來替換目標模式中的匹配與所提供的替換序列。
現在的問題歸結爲是否Matcher#replaceAll()
將返回原始字符串或新分配的拷貝,即使格局不匹配。通過閱讀Oracle庫中的代碼,如果Matcher
找不到要匹配的模式,它會在原始CharSequence
上返回CharSequence#toString()
,而對於String
對象,則返回this
引用不受影響。這讓我想知道你是否在報道真實的結果。
提出的問題中的一個明顯缺陷是String
的原始內容aStr
。你可能打算展示一個聲明,如
final String aStr = "Hello";
但你沒有。這兩個表達式的結果應取決於aStr
是否包含「H」字符。假設它的確如此,我認爲這兩個表達式都會產生錯誤,假設沒有string interning被String#replace()
重載發揮作用。我們知道字符串文字是被實施的,但是我們看到在Oracle庫的String#replace()
方法實現中構建的返回值是新分配的,並不是從實習池中提取的。
使用'.equals()'比較'字符串'。 –
'aStr'是否包含'H'字符? – seh
*大家*錯過了根本問題,它不是重複的!在這個特定的情況下,'replace(char,char)'的實現以'if(oldChar!= newChar){...}開始;' 因此,你的簡單測試返回相同的實例......這是爲什麼== ==成功了。正如已經提到的那樣,使用'equals'來比較對象的等價性,而不是檢查*相同*對象實例的'=='。 –