StringTokenizer 显示不需要的结果

StringTokenizer showing unwanted results

当我 运行 下面的代码时,我发现了一些东西 st运行ge.

下面程序的输出是token1=AAAAA token2=BBBBB|

不过,根据我的理解,应该是token1=AAAAA token2=BBBBB|DUMMY

public class TestToken {

    public static void main(final String[] args) {
        final String delim = "DELIM";
        String token1 = "AAAAA";
        String token2 = "BBBBB|DUMMY";
        final String input = token1 + delim + token2;
        final StringTokenizer tokenizer = new StringTokenizer(input, delim);
        final String text1 = tokenizer.nextToken();
        final String text2 = tokenizer.nextToken();
        System.out.println("token1=" + text1);
        System.out.println("token2=" + text2);
        System.out.println();
    }

}

谁能解释一下如何解决这个问题以及为什么会这样?

不,你的分隔符是 D E L I 和 M

查看 javadoc delim 参数中的所有字符都是分隔标记的分隔符。

delim - 分隔符。

考虑

    final String delim = "DELIM";
    String token1 = "AAAAA";
    String token2 = "BBBBB|ZUMMY";
    final String input = token1 + delim + token2;
    final StringTokenizer tokenizer = new StringTokenizer(input, delim);
    final String text1 = tokenizer.nextToken();
    final String text2 = tokenizer.nextToken();
    System.out.println("token1=" + text1);
    System.out.println("token2=" + text2);
    System.out.println();

摘自constructor's documentation

The characters in the delim argument are the delimiters for separating tokens.

也就是说每个字符是一个分隔符,而不是整个字符串。事实上,您有 5 个分隔符(字符 DELIM)。

用下面的代码可以看到效果

while (tokenizer.hasMoreTokens())
   System.out.println(tokenizer.nextToken());

打印出:

AAAAA
BBBBB|
U
Y

来自 StringTokenizer 的文档

Constructs a string tokenizer for the specified string. The characters in the delim argument are the delimiters for separating tokens. Delimiter characters themselves will not be treated as tokens.

这意味着 DELIM 不是分隔符,但其中的所有字符都是分隔符(即 DELI , 和 M).

当您运行以下代码时:

public static void main(final String[] args) {
    final String delim = "DELIM";
    String token1 = "AAAAA";
    String token2 = "BBBBB|DUMMY";
    final String input = token1 + delim + token2;
    final StringTokenizer tokenizer = new StringTokenizer(input, delim);
    while(tokenizer.hasMoreElements()){
        System.out.println("token =" + tokenizer.nextToken());
    }
}

它给出以下输出:

token =AAAAA
token =BBBBB|
token =U
token =Y

如您所见,您的输入在 DM 上被拆分(它们出现在您的输入中)。

StringTokenizer 接受一个字符串,其中 每个字符都是一个分隔符 。由于 D 是您的分隔符之一,因此第二个标记在 | 之后被截断。

如果您想使用多字符定界符,则必须使用不同的技术。例如,split:

String[] parts = Arrays.toString(input.split(delim)); 

如文档所述,delim 参数中的所有字符都是分隔标记的分隔符。

您需要做的是使用拆分功能。

public static void main(final String[] args) {
    final String delim = "DELIM";
    String token1 = "AAAAA";
    String token2 = "BBBBB|DUMMY";
    final String input = token1 + delim + token2;

    final String[] tokens = input.split("DELIM");
    for (String token:tokens) {
        System.out.println(token);
    }

}

有多个选项可以实现此功能。首先说说为什么会这样,我认为各种帖子都很好地解释了这是因为你的定界符不是 "DELIM",而是 "D"、"E"、"L","I","M"

现在,如果您想根据另一个字符串(例如 DELIM)来分隔字符串,您可以使用什么

选项 1: 使用字符串拆分方法,它将分隔符字符串作为参数,并将 return 标记数组

String statement = "AAAADELIMBBBB|DUMMY";
String tokens[] = statement.split("DELIM");

选项 2: 使用 splitAsStream 将语句作为参数,编译将正则表达式分隔符作为参数

Pattern.compile("DELIM").splitAsStream("AAAADELIMBBBB|DUMMY").forEach(System.out::println);

选项 3:使用 Stream.of 和拆分作为论据

Stream.of("AAAADELIMBBBB|DUMMY".split("DELIM")).forEach(System.out::println);

除了上述超酷的拆分方式外,如果您是 String Tokenizer 的铁杆粉丝并且只想使用它来实现它,您还可以使用带有 "D" 作为分隔符的 String Tokenizer 然后 for每个收到的令牌,可以检查前四个字符是 "ELIM"。如果是,则将 remaninng 子字符串作为令牌并与进一步接收令牌连接,如果不是,则在开始时附加 D,然后附加当前令牌。