奇怪的Java字符串比较

时间:2011-10-15 12:07:41

标签: java string-comparison

我在使用Java String比较时遇到了一个小问题。

我编写了一个类,它接受一个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));

具有以下输出; (注意“:” - 用作描述符,所以我可以确保没有额外的空格)

:(a|b):(a|b):
:((a|b)|c):((a|b)|c):
-1
-1
false
false

基于分别手动比较字符串exp1和exp2与t1和t2,它们完全相同。但由于某种原因,Java坚持认为它们是不同的。

这不是使用==而不是.equals()的明显错误,但我很难过为什么两个看似相同的字符串不同。任何帮助将不胜感激:))

3 个答案:

答案 0 :(得分: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上运行它,但空字符显示为空格。)

答案 1 :(得分:2)

嗯,肯定看起来没关系。我要做的是使用charAt迭代两个字符串,将每个字符与另一个字符串中的等效字符进行比较。这至少会有希望告诉你有问题的人物。

还输出关于两个字符串的所有其他内容,例如长度。

可能是其中一个角色,虽然看起来相同,可能是其他一些Unicode分身: - )

您可能还想捕获该输出并在其上执行详细的二进制转储,例如将其加载到gvim并使用十六进制转换工具,或者在捕获的输出上执行od -xcb(如果可用)。当你进入二元考试水平时,可能会有明显的不同。

答案 2 :(得分:1)

我有一些建议

  • 复制每个输出并粘贴到记事本(或任何类似的编辑器)中,然后 再次复制它们并执行类似的操作

    的System.out.println( “(A | B)” 与compareToIgnoreCase( “(A | B)”));

  • 打印出每个字符的整数表示。如果它是一个奇怪的unicode,int表示将是不同的。

  • 您使用的是哪个版本的JDK?