[英]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
如果您錯過StringTokenizer
的Enumeration
本質,請獲取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
類如何將它們識別為單獨的字符?
String
有一個名為charAt
和codePointAt
,該方法返回索引處的字符或代碼點:
"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
僅支持單個字符定界符。 如果要使用字符串作為分隔符,則可以改用Scanner
或String.split
。 對於這兩種情況,定界符均以正則表達式表示 ,因此您必須使用"\\\\.\\\\?!"
代替。 您可以在此處了解有關正則表達式的更多信息
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.