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類,并提供一些實際示例進行實戰。