簡體   English   中英

奇怪的Java字符串比較

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM