奇怪的Java字符串比较

奇怪的Java字符串比较,java,string-comparison,Java,String Comparison,我在Java字符串比较方面遇到了一个小问题 我编写了一个类,它接收字符串并将其解析为自定义树类型。我已经编写了一个toString类,然后将该树再次转换回字符串。作为单元测试的一部分,我只是检查toString方法生成的字符串是否与最初解析的字符串相同 这是我的简单测试和一些打印输出,这样我们可以看到发生了什么 final String exp1 = "(a|b)"; final String exp2 = "((a|b)|c)"; final Node tree1 = Reader.parse

我在Java字符串比较方面遇到了一个小问题

我编写了一个类,它接收字符串并将其解析为自定义树类型。我已经编写了一个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));
具有以下输出;(注意“:”-用作轮廓线,因此我可以确保没有额外的空白)

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

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

嗯,看起来确实不错。我要做的是使用
charAt
对两个字符串进行迭代,将每个字符与另一个字符串中的等效字符进行比较。这至少会告诉你冒犯的角色

还输出关于这两个字符串的所有其他信息,例如长度

可能是其中一个字符看起来相同,但可能是其他Unicode doppelganger:-)


您可能还希望捕获该输出并对其执行详细的二进制转储,例如将其加载到gvim并使用十六进制转换工具,或者对捕获的输出执行
od-xcb
(如果可用)。当您进入二进制检查级别时,可能会有明显的差异。

您的字符串中是否有空字符?使用
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 :a | b:a | b: 假的
(我也在Windows上运行了它,但是空字符显示为空格。)

我有一些建议

  • 复制每个输出并粘贴到记事本(或任何类似编辑器)中,然后 再复制一次,然后像这样做

    System.out.println(“(a | b)”.compareTignoreCase(“(a | b)”)

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

  • 另外,您使用的是什么版本的JDK


尝试使用差异工具对其进行比较,这将显示哪些字符不同。或者这就是您所说的“手动比较”的意思?为了提供帮助,我们需要查看解析和toString代码。@DonRoby当然问题在于比较两个看似相同的字符串,而不是它们的生成方式。我很乐意发布代码,因为它可能有助于更快地找到解决方案,但目前有点混乱。@NateC-K我的意思只是一个视觉比较。你会推荐什么不同的工具?(我是linux/mac用户,所以终端命令会很棒)@ChrisSalij:尝试将输出管道化到hextump(
java whatch…| hextump-C
)并仔细查看输出。我也这么想,但我编写了一个简单的循环,循环遍历字符串,它说每个字符都是相同的。这似乎是原因。我知道空字符,但没有考虑检查它们。我只得到exp1(5)的长度和t1(6)的长度,所以我假设我在末尾添加了一个空字符。谢谢:) :a|b:a|b: false