天天看點

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

繼續閱讀