[Google Guava] 6-字串處理:分割,連線,填充
聯結器[Joiner]
用分隔符把字串序列連線起來也可能會遇上不必要的麻煩。如果字串序列中含有null,那連線操作會更難。Fluent風格的Joiner讓連線字串更簡單。
Joiner joiner = Joiner.on("; ").skipNulls(); return joiner.join("Harry", null, "Ron", "Hermione");
上述程式碼返回”Harry; Ron; Hermione”。另外,useForNull(String)方法可以給定某個字串來替換null,而不像skipNulls()方法是直接忽略null。 Joiner也可以用來連線物件型別,在這種情況下,它會把物件的toString()值連線起來。
Joiner.on(",").join(Arrays.asList(1, 5, 7)); // returns "1,5,7"
警告:joiner例項總是不可變的。用來定義joiner目標語義的配置方法總會返回一個新的joiner例項。這使得joiner例項都是執行緒安全的,你可以將其定義為static final常量。
拆分器[Splitter]
JDK內建的字串拆分工具有一些古怪的特性。比如,String.split悄悄丟棄了尾部的分隔符。 問題:”,a,,b,”.split(“,”)返回?
- “”, “a”, “”, “b”, “”
- null, “a”, null, “b”, null
- “a”, null, “b”
- “a”, “b”
- 以上都不對
正確答案是5:””, “a”, “”, “b”。只有尾部的空字串被忽略了。 Splitter使用令人放心的、直白的流暢API模式對這些混亂的特性作了完全的掌控。
Splitter.on(',') .trimResults() .omitEmptyStrings() .split("foo,bar,, qux");
上述程式碼返回Iterable<String>,其中包含”foo”、”bar”和”qux”。Splitter可以被設定為按照任何模式、字元、字串或字元匹配器拆分。
拆分器工廠
拆分器修飾符
如果你想要拆分器返回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。 所有這些方法指向兩個概念上的問題:
- 怎麼才算匹配字元?
- 如何處理這些匹配字元?
為了收拾這個泥潭,我們開發了CharMatcher。
直觀上,你可以認為一個CharMatcher例項代表著某一類字元,如數字或空白字元。事實上來說,CharMatcher例項就是對字元的布林判斷——CharMatcher確實也實現了Predicate<Character>——但類似”所有空白字元”或”所有小寫字母”的需求太普遍了,Guava因此建立了這一API。
然而使用CharMatcher的好處更在於它提供了一系列方法,讓你對字元作特定型別的操作:修剪[trim]、摺疊[collapse]、移除[remove]、保留[retain]等等。CharMatcher例項首先代表概念1:怎麼才算匹配字元?然後它還提供了很多操作概念2:如何處理這些匹配字元?這樣的設計使得API複雜度的線性增加可以帶來靈活性和功能兩方面的增長。
String noControl = CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); //移除control字元 String theDigits = CharMatcher.DIGIT.retainFrom(string); //只保留數字字元 String spaced = CharMatcher.WHITESPACE.trimAndCollapseFrom(string, ' '); //去除兩端的空格,並把中間的連續空格替換成單個空格 String noDigits = CharMatcher.JAVA_DIGIT.replaceFrom(string, "*"); //用*號替換所有數字 String lowerAndDigit = CharMatcher.JAVA_DIGIT.or(CharMatcher.JAVA_LOWER_CASE).retainFrom(string); // 只保留數字和小寫字母
注:CharMatcher只處理char型別代表的字元;它不能理解0x10000到0x10FFFF的Unicode 增補字元。這些邏輯字元以代理對[surrogate pairs]的形式編碼進字串,而CharMatcher只能將這種邏輯字元看待成兩個獨立的字元。
獲取字元匹配器
CharMatcher中的常量可以滿足大多數字符匹配需求:
其他獲取字元匹配器的常見方法包括:
方法 | 描述 |
列舉匹配字元。如CharMatcher.anyOf(“aeiou”)匹配小寫英語母音 | |
給定字元範圍匹配,如CharMatcher.inRange(‘a’, ‘z’) |
使用字元匹配器
CharMatcher提供了多種多樣的方法操作CharSequence中的特定字元。其中最常用的羅列如下:
所有這些方法返回String,除了matchesAllOf返回的是boolean。
字符集[Charsets]
不要這樣做字符集處理:
try { bytes = string.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { // how can this possibly happen? throw new AssertionError(e); }
試試這樣寫:
bytes = string.getBytes(Charsets.UTF_8);
Charsets針對所有Java平臺都要保證支援的六種字符集提供了常量引用。嘗試使用這些常量,而不是通過名稱獲取字符集例項。
大小寫格式[CaseFormat]
CaseFormat被用來方便地在各種ASCII大小寫規範間轉換字串——比如,程式語言的命名規範。CaseFormat支援的格式如下:
CaseFormat的用法很直接:
CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, "CONSTANT_NAME")); // returns "constantName"
我們CaseFormat在某些時候尤其有用,比如編寫程式碼生成器的時候。