Skip to main content
 首页 » 编程设计

Java StringTokenizer快速指南

2022年07月19日134powertoolsteam

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’再次分割。

tokens.add(tokenizer.nextToken("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文件如下:

1|IND|India 
2|MY|Malaysia 
3|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类,并提供一些实际示例进行实战。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/80504462
阅读延展