【问题标题】:Mysterious Whitespace with Stringbuilder使用 Stringbuilder 的神秘空白
【发布时间】:2014-02-16 15:52:02
【问题描述】:

我正在编写一个小计算器应用程序,并使用一个简单的标记器将用户输入解析为列表以供后续处理。

方法如下:

public LinkedList<String> tokenize(String infix) throws Exception 
{
    LinkedList<String> tokens = new LinkedList<String>();
    StringBuilder operand = new StringBuilder("");

    char current;

    int index = 0;
    while(index <= infix.length() -1) {
        current = infix.charAt(index);

        if(!isOperator(current)) {
            operand.append(current);
        } else {
            // Add the operand stack
            tokens.add(operand.toString());
            operand = new StringBuilder("");
            // Add the operator
            tokens.add(Character.toString(current));
        }
        index++;
    }
    // The trailing operator
    tokens.add(operand.toString());
    return tokens;
}

我为此方法设置的测试如下所示:

public void testTokenizer() throws Exception 
{   
    LinkedList<String> list = parser.tokenize("35+35");
    assertTrue(list.get(0) == "35" &&
        list.get(1) == "+"  &&
        list.get(2) == "35");
}

但是,这失败了,因为标记器似乎在标记中添加了空格。例如,打印从字符串“35+35”标记化的列表会给我:

[35, +, 35]

这是怎么回事?

【问题讨论】:

  • 还要注意字符串比较是错误的,不能用==来测试相等性,用equals()。例如:"35".equals(list.get(0))

标签: java string stringbuilder


【解决方案1】:

这是由在调用List#toString 期间创建List 的字符串表示的方式引起的。这基本上实现为

firstElement + ", " + secondElement + ", " + ....

所以这些空格不在元素中,而只在列表本身的字符串表示中。

编辑:您也可以通过打印类似的内容来验证这一点

System.out.println(">"+list.get(1)+"<");

这将打印出来

>+<

而不是

> +<

【讨论】:

    【解决方案2】:

    标记器没有为标记添加空间。当您显示列表时,很可能是由LinkedList's toString() 方法完成的:

    字符串表示由集合元素的列表组成,按其迭代器返回的顺序排列,用方括号 ("[]") 括起来。相邻元素由字符 ", "(逗号和空格)分隔。

    断言不起作用,因为它使用了==。例如,list.get(0) == "35" 应该是 list.get(0).equals("35")。这些是运行时 String 对象,而不是编译时常量,所以 == 不会用于比较。

    【讨论】:

    • 该死的。我应该抓住那个!谢谢。
    【解决方案3】:

    您的测试失败,因为它不正确地比较字符串。

    如果您将其更改为按您应该使用的.equals 方法,则此测试通过。

    @Test
    public void testTokenizer() throws Exception
    {
        LinkedList<String> list = parser.tokenize("35+35");
        assertTrue(list.get(0).equals("35")
                && list.get(1).equals("+")
                && list.get(2).equals("35"));
    }
    

    分词器没有添加空格。

    【讨论】: