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类,并提供一些实际示例进行实战。