[英]Weird Java String comparison
我在Java字符串比較中有一個小問題。
我編寫了一個包含String並將其解析為自定義樹類型的類。 我編寫了一個toString類,然后將該樹再次轉換回String。 作為單元測試的一部分,我只是檢查toString方法生成的String是否與最初解析的String相同。
這是我的簡單測試,上面有一些打印輸出,因此我們可以看到發生了什么。
final String exp1 = "(a|b)";
final String exp2 = "((a|b)|c)";
final Node tree1 = Reader.parseExpression2(exp1);
final Node tree2 = Reader.parseExpression2(exp2);
final String t1 = tree1.toString();
final String t2 = tree2.toString();
System.out.println(":" + exp1 + ":" + t1 + ":");
System.out.println(":" + exp2 + ":" + t2 + ":");
System.out.println(exp1.compareToIgnoreCase(t1));
System.out.println(exp2.compareToIgnoreCase(t2));
System.out.println(exp1.equals(t1));
System.out.println(exp2.equals(t2));
具有以下輸出; (NB“:”-用作輪廓符,因此我可以確保沒有多余的空格)
:(a|b):(a|b):
:((a|b)|c):((a|b)|c):
-1
-1
false
false
基於分別將字符串exp1和exp2分別與t1和t2比較,它們是完全相同的。 但是出於某種原因,Java堅持認為它們是不同的。
這不是使用==
代替.equals()
的明顯錯誤,但是我為為什么兩個看似相同的字符串不同而.equals()
。 任何幫助將非常感激 :)
您的字符串之一中是否包含空字符? 當您使用System.out.println(...)
時,這些可能不可見。
例如,考慮此類:
public class StringComparison {
public static void main(String[] args) {
String s = "a|b";
String t = "a|b\0";
System.out.println(":" + s + ":" + t + ":");
System.out.println(s.equals(t));
}
}
當我在Linux上運行時,它給出了以下輸出:
:a|b:a|b: false
(我也在Windows上運行它,但空字符顯示為空格。)
好吧, 看起來當然還可以。 我要做的是使用charAt
遍歷兩個字符串,以比較每個單個字符與另一個字符串中的等效字符。 至少,這有望告訴您令人反感的角色。
同時輸出您可以找到的關於字符串的其他所有信息,例如長度。
看起來可能相同,但其中一個字符可能是其他一些Unicode doppelganger :-)
您可能還想捕獲該輸出並對其進行詳細的二進制轉儲,例如將其加載到gvim中並使用十六進制轉換工具,或者對捕獲的輸出執行od -xcb
(如果可用)。 當您降至二元考試水平時,可能會有明顯的不同。
我有一些建議
復制每個輸出並粘貼到記事本(或任何類似的編輯器)中,然后再次復制它們並執行類似的操作
的System.out.println( “(A | B)” 與compareToIgnoreCase( “(A | B)”)。);
打印出每個字符的整數表示。 如果是奇怪的unicode,則int表示形式將有所不同。
您還在使用什么版本的JDK?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.