2011-10-15 83 views
2

我在Java String比較中遇到小問題。奇怪的Java字符串比較

我寫了一個類,它接受一個String並將其解析爲一個自定義樹類型。我寫了一個toString類,然後再將此樹轉換回字符串。作爲我的單元測試的一部分,我只是檢查由toString方法生成的字符串是否與首先解析的字符串相同。

這裏是我的一些簡單的測試打印輸出,以便我們可以看到發生了什麼。

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()的明顯錯誤,但我很難理解爲什麼兩個看起來相同的字符串是不同的。任何幫助將不勝感激:)

+0

嘗試將它們與diff工具進行比較,它會告訴您哪些字符不同。或者那是你「手動比較」的意思? –

+2

爲了提供幫助,我們需要查看解析和toString代碼。 –

+0

@DonRoby當然,問題在於比較看似完全相同的兩個字符串,而不是它們如何生成。我會很高興地發佈代碼,因爲它可以幫助更快地找到解決方案,但目前情況有點混亂。 –

回答

3

你的一個字符串中是否有空字符?當您使用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上,但空字符出現了一個空格。)

+0

這似乎是原因。我知道空字符,但沒有考慮檢查它們。我只是得到exp1(5)的長度和t1(6)的長度,所以我假設我以某種方式在末尾添加了一個空字符。謝謝 :) –

2

那麼,它當然看起來好吧。我會做的是迭代兩個字符串使用charAt比較每個單個字符與另一個字符串中的等價物。這至少可以告訴你這個冒犯的角色。

還輸出其他所有關於這兩個字符串的信息,例如長度。

這可能是其中一個角色,同時尋找相同的,可能是一些其他的Unicode分身:-)

您可能還需要捕獲輸出,並做就可以了詳細的二進制轉儲,如將其加載到gvim並使用十六進制轉換工具,或在捕獲的輸出上執行od -xcb(如果可用)。當您進入二進制考試級別時,可能會有明顯的差異。

+0

我也在想,但是我寫了一個簡單的循環遍歷字符串,它說每個字符都是相同的。 –

1

我有一些建議

  • 複製每個輸出並在記事本粘貼(或任何類似的編輯器),然後 再次複製他們做這樣的事情

    的System.out.println( 「(A | B)」。與compareToIgnoreCase(「(一| b)「));

  • 打印出每個字符的整數表示形式。如果它是一個奇怪的Unicode,int表示將會不同。

  • 您還正在使用哪個版本的JDK?