2011-10-15 82 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?