天天看点

Java StringTokenizer快速指南Java StringTokenizer快速指南

Java StringTokenizer快速指南

本文我们探讨java 基本的类 StringTokenizer。

StringTokenizer

StringTokenizer类可以帮助我们把字符串分割为多个符号(token)。

StreamTokenizer提供类似的功能,但StringTokenizer方法比使用StreamTokenizer类简单得多。StringTokenizer方法不区分标识符,数字和引号字符串,也不忽略注释。

分隔符集合(用于分割字符串的符号)可以在创建时指定,也可以基于每个符号。

StringTokenizer应用

最简单的示例是使用StringTokenizer基于特定分隔符分割字符串。下面示例分割参数字符串并生成符号列表。

public List<String> getTokens(String str) {
    List<String> tokens = new ArrayList<>();
    StringTokenizer tokenizer = new StringTokenizer(str, ",");
    while (tokenizer.hasMoreElements()) {
        tokens.add(tokenizer.nextToken());
    }
    return tokens;
}
           

我们打断字符串,基于分隔符“,”,然后循环增加至list。

举例,如果用户给定参数为 “Welcome,to,baeldung.com“, 该方法返回list包括三个符号元素:“Welcome“, “to” and “baeldung.com“。

java8 方法

既然StringTokenizer实现了Enumeration 接口,我们可以和java的Collections 接口一起使用。如果我们想用更简单的方法,可以基于Stream 和Collections.list() 方法实现:

public List<String> getTokensWithCollection(String str) {
    return Collections.list(new StringTokenizer(str, ",")).stream()
      .map(token -> (String) token)
      .collect(Collectors.toList());
}
           

在Collections.list()方法中我们直接传入StringTokenizer作为参数。既然Enumeration是对象类型,我们需要类型转换为String类型(这依赖业务,如果有需要,可能转换为Integer/Float)

StringTokenizer构造函数

除了缺省构造函数StringTokenizer(String str),StringTokenizer重载了两个构造函数StringTokenizer(String str, String delim) 和 StringTokenizer(String str, String delim, boolean returnDelims) 。

StringTokenizer(String str, String delim, boolean returnDelims) 参数包括布尔型returnDelims,true表示分隔符自身需要返回,最终返回符号包括分隔符.

StringTokenizer(String str) 上面构造函数的简化版本; 其内部调用其他构造函数,并通过硬代码指明分隔符为” \t\n\r\f” ,并且最后布尔参数为false。

自定义Token

StringTokenizer 提供了nextToken()的重载方法,带有字符串输入参数。其作为附加分隔符,让原符号基于附加分隔符再次分割,示例,如果我们在nextToken()方法中传入’e’,则会基于‘e’再次分割。

如果,给定字符串为“hello,baeidu.com”

H
llo
ba
idu.com
           

Token长度

我们可以通过countTokens方法,返回生成符号长度,当日也可以直接调用结果list.size()。

读csv文件

下面通过StringTokenizer实现一个真实的需求,从csv文件中读取信息,基于用户给定的分隔符进行解析数据:

public List<String> getTokensFromFile( String path , String delim ) {
    List<String> tokens = new ArrayList<>();
    String currLine = "";
    StringTokenizer tokenizer;
    try (BufferedReader br = new BufferedReader(
        new InputStreamReader(Application.class.getResourceAsStream( "/" + path )))) {
        while (( currLine = br.readLine()) != null ) {
            tokenizer = new StringTokenizer( currLine , delim );
            while (tokenizer.hasMoreElements()) {
                tokens.add(tokenizer.nextToken());
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return tokens;
}
           

函数带两个参数,一个是csv文件名称(如 [src -> main -> resources]文件夹),另一个为分隔符。

基于上述两个参数,逐行读取数据,然后使用StringTokenizer获取每行的分割信息。

加入csv文件如下:

|IND|India
|MY|Malaysia
|AU|Australia
           

则生成结果为:

1
IND
India
2
MY
Malaysia
3
AU
Australia
           

单元测试

上面示例对应单元测试方法为:

public class TokenizerTest {

    private MyTokenizer myTokenizer = new MyTokenizer();
    private List<String> expectedTokensForString = Arrays.asList(
      "Welcome" , "to" , "baeldung.com" );
    private List<String> expectedTokensForFile = Arrays.asList(
      "1" , "IND" , "India" , 
      "2" , "MY" , "Malaysia" , 
      "3", "AU" , "Australia" );

    @Test
    public void givenString_thenGetListOfString() {
        String str = "Welcome,to,baeldung.com";
        List<String> actualTokens = myTokenizer.getTokens( str );

        assertEquals( expectedTokensForString, actualTokens );
    }

    @Test
    public void givenFile_thenGetListOfString() {
        List<String> actualTokens = myTokenizer.getTokensFromFile( 
          "data.csv", "|" );

        assertEquals( expectedTokensForFile , actualTokens );
    }
}
           

总结

本文我们说明了如何使用Java StringTokenizer类,并提供一些实际示例进行实战。

继续阅读