字符串處理:分割,連接,填充 Google Guava

連接器[Joiner]

用分隔符把字符串序列連接起來也可能會遇上不必要的麻煩。如果字符串序列中含有null,那連接操作會更難。Fluent風格的Joiner讓連接字符串更簡單。

1 Joiner joiner = Joiner.on("; ").skipNulls();
2 return joiner.join("Harry"null"Ron""Hermione");

上述代碼返回”Harry; Ron; Hermione”。另外,useForNull(String)方法可以給定某個字符串來替換null,而不像skipNulls()方法是直接忽略null。 Joiner也可以用來連接對象類型,在這種情況下,它會把對象的toString()值連接起來。

1 Joiner.on(",").join(Arrays.asList(157)); // returns "1,5,7"

警告:joiner實例總是不可變的。用來定義joiner目標語義的配置方法總會返回一個新的joiner實例。這使得joiner實例都是線程安全的,你可以將其定義爲static final常量。

拆分器[Splitter]

JDK內建的字符串拆分工具有一些古怪的特性。比如,String.split悄悄丟棄了尾部的分隔符。 問題:”,a,,b,”.split(“,”)返回?

  1. “”, “a”, “”, “b”, “”
  2. null, “a”, null, “b”, null
  3. “a”, null, “b”
  4. “a”, “b”
  5. 以上都不對

正確答案是5:””, “a”, “”, “b”。只有尾部的空字符串被忽略了。 Splitter使用令人放心的、直白的流暢API模式對這些混亂的特性作了完全的掌控。

1 Splitter.on(',')
2         .trimResults()
3         .omitEmptyStrings()
4         .split("foo,bar,,   qux");

上述代碼返回Iterable<String>,其中包含”foo”、”bar”和”qux”。Splitter可以被設置爲按照任何模式、字符、字符串或字符匹配器拆分。

拆分器工廠

方法 描述 範例
Splitter.on(char) 按單個字符拆分 Splitter.on(‘;’)
Splitter.on(CharMatcher) 按字符匹配器拆分 Splitter.on(CharMatcher.BREAKING_WHITESPACE)
Splitter.on(String) 按字符串拆分 Splitter.on(“,   “)
Splitter.on(Pattern)Splitter.onPattern(String) 按正則表達式拆分 Splitter.onPattern(“\r?\n”)
Splitter.fixedLength(int) 按固定長度拆分;最後一段可能比給定長度短,但不會爲空。 Splitter.fixedLength(3)

拆分器修飾符

方法 描述
omitEmptyStrings() 從結果中自動忽略空字符串
trimResults() 移除結果字符串的前導空白和尾部空白
trimResults(CharMatcher) 給定匹配器,移除結果字符串的前導匹配字符和尾部匹配字符
limit(int) 限制拆分出的字符串數量

如果你想要拆分器返回List,只要使用Lists.newArrayList(splitter.split(string))或類似方法。 警告:splitter實例總是不可變的。用來定義splitter目標語義的配置方法總會返回一個新的splitter實例。這使得splitter實例都是線程安全的,你可以將其定義爲static final常量。

字符匹配器[CharMatcher]

在以前的Guava版本中,StringUtil類瘋狂地膨脹,其擁有很多處理字符串的方法:allAscii、collapse、collapseControlChars、collapseWhitespace、indexOfChars、lastIndexNotOf、numSharedChars、removeChars、removeCrLf、replaceChars、retainAllChars、strip、stripAndCollapse、stripNonDigits。 所有這些方法指向兩個概念上的問題:

  1. 怎麼纔算匹配字符?
  2. 如何處理這些匹配字符?

爲了收拾這個泥潭,我們開發了CharMatcher。

直觀上,你可以認爲一個CharMatcher實例代表着某一類字符,如數字或空白字符。事實上來說,CharMatcher實例就是對字符的布爾判斷——CharMatcher確實也實現了Predicate<Character>——但類似”所有空白字符”或”所有小寫字母”的需求太普遍了,Guava因此創建了這一API。

然而使用CharMatcher的好處更在於它提供了一系列方法,讓你對字符作特定類型的操作:修剪[trim]、摺疊[collapse]、移除[remove]、保留[retain]等等。CharMatcher實例首先代表概念1:怎麼纔算匹配字符?然後它還提供了很多操作概念2:如何處理這些匹配字符?這樣的設計使得API複雜度的線性增加可以帶來靈活性和功能兩方面的增長。

1 String noControl = CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); //移除control字符
2 String theDigits = CharMatcher.DIGIT.retainFrom(string); //只保留數字字符
3 String spaced = CharMatcher.WHITESPACE.trimAndCollapseFrom(string, ' ');
4 //去除兩端的空格,並把中間的連續空格替換成單個空格
5 String noDigits = CharMatcher.JAVA_DIGIT.replaceFrom(string, "*"); //用*號替換所有數字
6 String lowerAndDigit = CharMatcher.JAVA_DIGIT.or(CharMatcher.JAVA_LOWER_CASE).retainFrom(string);
7 // 只保留數字和小寫字母

注:CharMatcher只處理char類型代表的字符;它不能理解0x10000到0x10FFFF的Unicode 增補字符。這些邏輯字符以代理對[surrogate pairs]的形式編碼進字符串,而CharMatcher只能將這種邏輯字符看待成兩個獨立的字符。

獲取字符匹配器

CharMatcher中的常量可以滿足大多數字符匹配需求:

ANY NONE WHITESPACE BREAKING_WHITESPACE
INVISIBLE DIGIT JAVA_LETTER JAVA_DIGIT
JAVA_LETTER_OR_DIGIT JAVA_ISO_CONTROL JAVA_LOWER_CASE JAVA_UPPER_CASE
ASCII SINGLE_WIDTH    

其他獲取字符匹配器的常見方法包括:

方法 描述
anyOf(CharSequence) 枚舉匹配字符。如CharMatcher.anyOf(“aeiou”)匹配小寫英語元音
is(char) 給定單一字符匹配。
inRange(char, char) 給定字符範圍匹配,如CharMatcher.inRange(‘a’, ‘z’)

此外,CharMatcher還有negate()and(CharMatcher)or(CharMatcher)方法。

使用字符匹配器

CharMatcher提供了多種多樣的方法操作CharSequence中的特定字符。其中最常用的羅列如下:

方法 描述
collapseFrom(CharSequence,   char) 把每組連續的匹配字符替換爲特定字符。如WHITESPACE.collapseFrom(string, ‘ ‘)把字符串中的連續空白字符替換爲單個空格。
matchesAllOf(CharSequence) 測試是否字符序列中的所有字符都匹配。
removeFrom(CharSequence) 從字符序列中移除所有匹配字符。
retainFrom(CharSequence) 在字符序列中保留匹配字符,移除其他字符。
trimFrom(CharSequence) 移除字符序列的前導匹配字符和尾部匹配字符。
replaceFrom(CharSequence,   CharSequence) 用特定字符序列替代匹配字符。

所有這些方法返回String,除了matchesAllOf返回的是boolean。

字符集[Charsets]

不要這樣做字符集處理:

1 try {
2     bytes = string.getBytes("UTF-8");
3 catch (UnsupportedEncodingException e) {
4     // how can this possibly happen?
5     throw new AssertionError(e);
6 }

試試這樣寫:

1 bytes = string.getBytes(Charsets.UTF_8);

Charsets針對所有Java平臺都要保證支持的六種字符集提供了常量引用。嘗試使用這些常量,而不是通過名稱獲取字符集實例。

大小寫格式[CaseFormat]

CaseFormat被用來方便地在各種ASCII大小寫規範間轉換字符串——比如,編程語言的命名規範。CaseFormat支持的格式如下:

格式 範例
LOWER_CAMEL lowerCamel
LOWER_HYPHEN lower-hyphen
LOWER_UNDERSCORE lower_underscore
UPPER_CAMEL UpperCamel
UPPER_UNDERSCORE UPPER_UNDERSCORE

CaseFormat的用法很直接:

1 CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, "CONSTANT_NAME")); // returns "constantName"

我們CaseFormat在某些時候尤其有用,比如編寫代碼生成器的時候。

原創文章,轉載請註明: 轉載自併發編程網 – ifeve.com本文鏈接地址: [Google Guava] 6-字符串處理:分割,連接,填充

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章