簡體   English   中英

將多個定界符傳遞給StringTokenizer構造函數

[英]Passing multiple delimiters to StringTokenizer constructor

我已經看到了將多個定界符(例如“。”,“?”,“!”)傳遞給StringTokenizer構造函數的語法是:

StringTokenizer obj=new StringTokenizer(str,".?!");

我沒有得到的是,我將所有定界符都用雙引號括起來了,所以不是使它成為String而不是單個字符。 StringTokenizer類如何將它們識別為單獨的字符? 為什么是 ”。?!” 沒有被視為單個分隔符?

StringTokenizer是一個遺留類,出於兼容性原因而保留,盡管在新代碼中不鼓勵使用它。

所以,算了吧。

建議任何尋求此功能的人改用String的split方法或java.util.regex包。

因此,請改用String#split

String[] elements = str.split("\\.\\?!"); // treats ".?!" as a single delimiter
String[] elements2 = str.split("[.?!]"); // three delimiters 

如果您錯過StringTokenizerEnumeration本質,請獲取Iterator

Iterator<String> iterator = Arrays.asList(elements).iterator();
while (iterator.hasNext()) {
  String next = iterator.next();
  // ...
}

StringTokenizer類如何將它們識別為單獨的字符?

這是一個實現細節,您不必擔心。 有兩種方法可以做到這一點。 他們使用String#charAt(int)String#codePointAt(int)

為什么是 ”。?!” 沒有被視為單個分隔符?

這是他們所做的選擇:“我們將采取一個字符串,我們將尋找定界符在那兒 。” Javadoc對此很清楚。

  * * @param str a string to be parsed. * @param delim the delimiters. * @param returnDelims flag indicating whether to return the delimiters * as tokens. * @exception NullPointerException if str is <CODE>null</CODE> */ public StringTokenizer(String str, String delim, boolean returnDelims) { 

這就是StringTokenizer的定義方式。 只是看看javadoc

為指定的字符串構造一個字符串標記器。 delim參數中的所有字符都是用於分隔標記的定界符

同樣在源代碼中,您會發現delimiterCodePoints字段,描述如下

/**
 * When hasSurrogates is true, delimiters are converted to code
 * points and isDelimiter(int) is used to determine if the given
 * codepoint is a delimiter.
 */
private int[] delimiterCodePoints;

因此基本上每個delimiters都會轉換為存儲在數組中的int代碼-然后使用該數組確定該字符是否為定界符

的確,您傳遞的是單個字符串而不是單個字符,但是該字符串的處理取決於StringTokenizer StringTokenizer從定界符字符串中獲取每個字符,並將每個字符用作定界符。 這樣,您可以在多個不同的定界符上拆分字符串,而不必多次運行令牌生成器。

您可以在此處查看此功能的說明:

delim參數中的字符是用於分隔標記的定界符。

如果沒有為此參數傳遞任何內容,則默認為 " \\t\\n\\r\\f" ,它基本上只是空白。

StringTokenizer類如何將它們識別為單獨的字符?

String有一個名為charAtcodePointAt ,該方法返回索引處的字符或代碼點:

"abc".charAt(0) // 'a'

StringTokenizer的實現將在某些時候傳入的分隔符上使用這兩種方法。 在我的JDK版本中,定界符字符串的代碼點通過setMaxDelimCodePoint方法提取並添加到數組delimiterCodePoints中,該方法由構造函數調用:

私人無效setMaxDelimCodePoint(){// ...

    if (hasSurrogates) {
        delimiterCodePoints = new int[count];
        for (int i = 0, j = 0; i < count; i++, j += Character.charCount(c)) {
            c = delimiters.codePointAt(j); <--- notice this line
            delimiterCodePoints[i] = c;
        }
    }
}

然后在isDelimiter方法中訪問此數組,該方法確定一個字符是否為定界符:

private boolean isDelimiter(int codePoint) {
    for (int i = 0; i < delimiterCodePoints.length; i++) {
        if (delimiterCodePoints[i] == codePoint) {
            return true;
        }
    }
    return false;
}

當然,這不是可以設計API的唯一方法。 構造函數可以接受一個char數組作為定界符,但是我沒有資格說出設計者為什么這樣做。

為什么是 ”。?!” 沒有被視為單個分隔符?

StringTokenizer僅支持單個字符定界符。 如果要使用字符串作為分隔符,則可以改用ScannerString.split 對於這兩種情況,定界符均以正則表達式表示 ,因此您必須使用"\\\\.\\\\?!" 代替。 您可以在此處了解有關正則表達式的更多信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM