【问题标题】:java StringTokenizer unexpected resultsjava StringTokenizer 意外结果
【发布时间】:2014-03-09 07:37:55
【问题描述】:

我有以下代码将标记字符串以创建对象列表:

import java.util.StringTokenizer;


public class TestStringTokenizer {
    private final static String INTERNAL_DELIMETER = "#,#";
    private final static String EXTERNAL_DELIMETER = "#|#";
    public static void main(String[]aregs){
        String test= "1#,#Jon#,#176#|#2#,#Jack#,#200#|#3#,#Jimmy#,#160";
        StringTokenizer tokenizer = new StringTokenizer(test, EXTERNAL_DELIMETER);
        while(tokenizer.hasMoreElements()){
            System.out.println(tokenizer.nextElement());
            //later will take this token and extract elements
        }
    }
}

我期望的输出是
1#,#乔恩#,#176
2#,#杰克#,#200
3#,#吉米#,#160

我得到的是: 1
,
乔恩
,
176
2
,
杰克
,
200
3
,
吉米
,
160

如果我将内部分隔符更改为 它将正常工作 为什么会发生这种行为?

【问题讨论】:

  • StringTokenizer 不将 #|# 作为一个分隔符,而是作为 3 个分隔符。请仔细阅读该类的 API 以了解其工作原理。

标签: java stringtokenizer


【解决方案1】:

根据 StringTokenizer JavaDocs

http://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html

StringTokenizer 是一个遗留类,出于兼容性原因保留,但不鼓励在新代码中使用它。建议任何寻求此功能的人使用 String 的 split 方法或 java.util.regex 包。

改用 String.split:

String[] strArr = stringToSplit.split(INTERNAL_DELIMETER);

您需要做的唯一更改是 EXTERNAL_DELIMETER 中的或管道(“|”)是一个特殊的正则表达式字符,必须转义:“\\|”。

更多信息可以在 String.split Javadoc 中找到:

http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String)

【讨论】:

    【解决方案2】:

    StrinTokenizer 不能使用表达式作为分隔符,请改用 Scanner

        Scanner sc = new Scanner(test);
        sc.useDelimiter("#\\|#");
        while (sc.hasNext()) {
            System.out.println(sc.next());
        }
    

    【讨论】:

      【解决方案3】:

      StrinTokenizer构造函数的第二个参数是分隔符(每个字符都是一个分隔符)

      你可以使用 String.split 来代替

      public class TestStringTokenizer {
          private final static String INTERNAL_DELIMETER = "#,#";
          private final static String EXTERNAL_DELIMETER = "#|#";
          public static void main(String[]aregs){
              String test= "1#,#Jon#,#176#|#2#,#Jack#,#200#|#3#,#Jimmy#,#160";
              for (String s : test.split("#\\|#"))
                  System.out.println(s);
              }
          }
      }
      

      【讨论】:

      • 我很惊讶 split 只运行一次,像这样在 foreach 循环中。老实说,即使它确实有效,我也不会把它放在那里。令人困惑。
      • 它没有像预期的那样给出正确的 o/p ......我已经编辑了代码......现在它可以工作了
      • 我之前添加了一个转义字符 |因为 split 参数是一个正则表达式
      • for-each 循环的迭代器部分被求值一次得到一个迭代器
      • 您的代码有两个问题,但它们本身并不是真正的错误:您的答案中根本没有使用INTERNAL_DELIMETER,因此请考虑消除它。 EXTERNAL_DELIMITER 也没有被使用,但它应该被使用。不要使用EXTERNAL_DELIMITER 调用split,而是使用变量名调用它(并更改EXTERNAL_DELIMITER 的值,使其或管道被转义)。就目前而言,这个答案是正确,但写得很混乱。修复后我将删除此评论。只需回复@alliteralmind。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多