奇怪的Java字符串比较
我在Java字符串比较方面遇到了一个小问题 我编写了一个类,它接收字符串并将其解析为自定义树类型。我已经编写了一个toString类,然后将该树再次转换回字符串。作为单元测试的一部分,我只是检查toString方法生成的字符串是否与最初解析的字符串相同 这是我的简单测试和一些打印输出,这样我们可以看到发生了什么奇怪的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
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
java whatch…| hextump-C
)并仔细查看输出。我也这么想,但我编写了一个简单的循环,循环遍历字符串,它说每个字符都是相同的。这似乎是原因。我知道空字符,但没有考虑检查它们。我只得到exp1(5)的长度和t1(6)的长度,所以我假设我在末尾添加了一个空字符。谢谢:)
:a|b:a|b:
false