文章目录

  • 1.Ascii字符
    • 1.1判断是否小写
    • 1.2判断是否大写
    • 1.3返回小写
    • 1.4返回大写
    • 1.5忽略大小写判断
    • 1.6截断
    • 1.7使用示例
  • 2.CaseFormat大小写格式
    • 2.1to转换
    • 2.2converterTo转换
    • 2.3使用示例
  • 3.CharMatcher字符匹配器
    • 3.1获取字符匹配器
    • 3.2使用字符匹配器
    • 3.3使用示例
  • 4.Charsets字符集
    • 4.1使用示例
  • 5.Joiner连接器
    • 5.1使用示例
  • 6.Splitter拆分器
    • 6.1基本工厂
    • 6.2修饰符
    • 6.3Map拆分器
    • 6.4使用示例
  • 7.Strings字符串处理
    • 7.1静态方法
    • 7.2使用示例

使用示例时须导入以下jar包进行测试,guava版本使用28.2-jre

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>28.2-jre</version>
</dependency><dependency><groupId>com.google.truth</groupId><artifactId>truth</artifactId><version>1.0.1</version><scope>compile</scope>
</dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava-testlib</artifactId><version>28.2-jre</version><scope>compile</scope>
</dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>compile</scope>
</dependency>

Strings:一些非常有用的字符串工具:拆分,连接,填充等。

1.Ascii字符

与ASCII字符(值在0x000x7F范围内的字符)有关的静态方法,以及包含此类字符的字符串。

1.1判断是否小写

方法:boolean isLowerCase(char c)

指示c是否为’a’和’z’之间的26个小写ASCII字母字符之一。所有其他字符(包括非ASCII字符)都返回false。

1.2判断是否大写

方法:boolean isUpperCase(char c)

指示c是否为’A’和’Z’之间的26个小写ASCII字母字符之一。所有其他字符(包括非ASCII字符)都返回false。

1.3返回小写

方法:char toLowerCase(char c)

如果参数为isUpperCase(char)大写ASCII字符,则返回等效的小写字母。否则返回参数。

方法:String toLowerCase(CharSequence chars)

返回输入字符序列的副本,其中所有isUpperCase(char)大写ASCII字符都已转换为小写。所有其他字符均被复制而没有修改。

方法:String toLowerCase(String string)

返回输入字符串的副本,其中所有isUpperCase(char)大写ASCII字符都已转换为小写。所有其他字符均被复制而没有修改。

1.4返回大写

参见上一节

1.5忽略大小写判断

方法:boolean equalsIgnoreCase(CharSequence s1, CharSequence s2)

指示给定字符序列s1s2的内容是否相等,而忽略'a''z''A''Z'(含)之间的任何ASCII字母字符的情况。
此方法比String#equalsIgnoreCase明显快得多,如果已知至少一个参数仅包含ASCII字符,则应优先使用此方法。
但是请注意,此方法的行为并不总是与以下表达式相同:

string.toUpperCase().equals("UPPER CASE ASCII")
string.toLowerCase().equals("lower case ascii")

由于某些非ASCII字符的大小写折叠(在String#equalsIgnoreCase中不会发生)。但是,在几乎所有使用ASCII字符串的情况下,作者都可能希望此方法提供的行为,而不是toUpperCase()toLowerCase()的微妙且有时令人惊讶的行为。

1.6截断

方法:String truncate(CharSequence seq, int maxLength, String truncationIndicator)

将给定的字符序列截断为给定的最大长度。如果序列的长度大于maxLength,则返回的字符串> 的长度将精确为maxLength个字符,并以给定的truncationIndicator结尾。否则,序> > 列将以字符串形式返回,且内容不变。

示例:

Ascii.truncate("foobar", 7, "..."); // returns "foobar"
Ascii.truncate("foobar", 5, "..."); // returns "fo..."

注意: 此方法可以用于某些非ASCII文本,但与任意Unicode文本一起使用不安全。它主要用于与已知可以安全使用的文本(例如,全ASCII文本)和简单的调试文本一起使用。使用此方法时,请考虑以下事项:

  • 它可能会拆分代理对
  • 它可以分割字符并组合字符
  • 它不考虑单词边界
  • 如果要截断以显示给用户,则必须考虑其他因素
  • 适当的截断指示符可能取决于语言环境
  • 在截断指示器中使用非ASCII字符是安全的

如果maxLength小于truncationIndicator的长度,则throws IllegalArgumentException

1.7使用示例

import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Ascii;
import junit.framework.TestCase;public class AsciiTest extends TestCase {/*** The Unicode points {@code 00c1} and {@code 00e1} are the upper- and lowercase forms of* A-with-acute-accent, {@code Á} and {@code á}.*/private static final String IGNORED = "`10-=~!@#$%^&*()_+[]\\{}|;':\",./<>?'\u00c1\u00e1\n";private static final String LOWER = "abcdefghijklmnopqrstuvwxyz";private static final String UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";public void testToLowerCase() {assertEquals(LOWER, Ascii.toLowerCase(UPPER));assertSame(LOWER, Ascii.toLowerCase(LOWER));assertEquals(IGNORED, Ascii.toLowerCase(IGNORED));assertEquals("foobar", Ascii.toLowerCase("fOobaR"));}public void testToUpperCase() {assertEquals(UPPER, Ascii.toUpperCase(LOWER));assertSame(UPPER, Ascii.toUpperCase(UPPER));assertEquals(IGNORED, Ascii.toUpperCase(IGNORED));assertEquals("FOOBAR", Ascii.toUpperCase("FoOBAr"));}public void testCharsIgnored() {for (char c : IGNORED.toCharArray()) {String str = String.valueOf(c);assertTrue(str, c == Ascii.toLowerCase(c));assertTrue(str, c == Ascii.toUpperCase(c));assertFalse(str, Ascii.isLowerCase(c));assertFalse(str, Ascii.isUpperCase(c));}}public void testCharsLower() {for (char c : LOWER.toCharArray()) {String str = String.valueOf(c);assertTrue(str, c == Ascii.toLowerCase(c));assertFalse(str, c == Ascii.toUpperCase(c));assertTrue(str, Ascii.isLowerCase(c));assertFalse(str, Ascii.isUpperCase(c));}}public void testCharsUpper() {for (char c : UPPER.toCharArray()) {String str = String.valueOf(c);assertFalse(str, c == Ascii.toLowerCase(c));assertTrue(str, c == Ascii.toUpperCase(c));assertFalse(str, Ascii.isLowerCase(c));assertTrue(str, Ascii.isUpperCase(c));}}public void testTruncate() {assertEquals("foobar", Ascii.truncate("foobar", 10, "..."));assertEquals("fo...", Ascii.truncate("foobar", 5, "..."));assertEquals("foobar", Ascii.truncate("foobar", 6, "..."));assertEquals("...", Ascii.truncate("foobar", 3, "..."));assertEquals("foobar", Ascii.truncate("foobar", 10, "…"));assertEquals("foo…", Ascii.truncate("foobar", 4, "…"));assertEquals("fo--", Ascii.truncate("foobar", 4, "--"));assertEquals("foobar", Ascii.truncate("foobar", 6, "…"));assertEquals("foob…", Ascii.truncate("foobar", 5, "…"));assertEquals("foo", Ascii.truncate("foobar", 3, ""));assertEquals("", Ascii.truncate("", 5, ""));assertEquals("", Ascii.truncate("", 5, "..."));assertEquals("", Ascii.truncate("", 0, ""));}public void testTruncateIllegalArguments() {String truncated = null;try {truncated = Ascii.truncate("foobar", 2, "...");fail();} catch (IllegalArgumentException expected) {}try {truncated = Ascii.truncate("foobar", 8, "1234567890");fail();} catch (IllegalArgumentException expected) {}try {truncated = Ascii.truncate("foobar", -1, "...");fail();} catch (IllegalArgumentException expected) {}try {truncated = Ascii.truncate("foobar", -1, "");fail();} catch (IllegalArgumentException expected) {}}public void testEqualsIgnoreCase() {assertTrue(Ascii.equalsIgnoreCase("", ""));assertFalse(Ascii.equalsIgnoreCase("", "x"));assertFalse(Ascii.equalsIgnoreCase("x", ""));assertTrue(Ascii.equalsIgnoreCase(LOWER, UPPER));assertTrue(Ascii.equalsIgnoreCase(UPPER, LOWER));// Create new strings here to avoid early-out logic.assertTrue(Ascii.equalsIgnoreCase(new String(IGNORED), new String(IGNORED)));// Compare to: "\u00c1".equalsIgnoreCase("\u00e1") == trueassertFalse(Ascii.equalsIgnoreCase("\u00c1", "\u00e1"));// Test chars just outside the alphabetic range ('A'-1 vs 'a'-1, 'Z'+1 vs 'z'+1)assertFalse(Ascii.equalsIgnoreCase("@", "`"));assertFalse(Ascii.equalsIgnoreCase("[", "{"));}@GwtIncompatible // String.toUpperCase() has browser semanticspublic void testEqualsIgnoreCaseUnicodeEquivalence() {// Note that it's possible in future that the JDK's idea to toUpperCase() or equalsIgnoreCase()// may change and break assumptions in this test [*]. This is not a bug in the implementation of// Ascii.equalsIgnoreCase(), but it is a signal that its documentation may need updating as// regards edge cases.// The Unicode point {@code 00df} is the lowercase form of sharp-S (ß), whose uppercase is "SS".assertEquals("PASSWORD", "pa\u00dfword".toUpperCase()); // [*]assertFalse("pa\u00dfword".equalsIgnoreCase("PASSWORD")); // [*]assertFalse(Ascii.equalsIgnoreCase("pa\u00dfword", "PASSWORD"));}
}

2.CaseFormat大小写格式

在各种ASCII大小写格式之间进行转换的实用程序类。对于非ASCII输入,行为未定义。

CaseFormat是一个方便的枚举类,用于在ASCII大小写约定之间进行转换——例如,编程语言的命名约定。支持的格式包括:

枚举 说明 描述
LOWER_HYPHEN 小写连字符 连字符的变量命名约定,例如"lower-hyphen"
LOWER_UNDERSCORE 全小写下划线 C++变量命名约定,例如"lower_underscore"
LOWER_CAMEL 小写驼峰 Java变量命名约定,例如"lowerCamel"
UPPER_CAMEL 大写驼峰 Java和C++类的命名约定,例如"UpperCamel"
UPPER_UNDERSCORE 全大写下划线 Java和C++常量命名约定,例如"UPPER_UNDERSCORE"

使用它相对简单:

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

例如,在编写代码生成器时,我们发现这特别有用。

2.1to转换

方法:String to(CaseFormat format, String str)

将指定的String str从此格式转换为指定的format格式。采取“尽力而为”的方法;如果str不符合假定的格式,则此方法的行为未定义,但无论如何我们都会做出合理的努力。

2.2converterTo转换

方法:Converter<String, String> converterTo(CaseFormat targetFormat)

返回一个Converter,它将字符串从此格式转换为目标格式targetFormat

2.3使用示例

import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.CaseFormat;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
import junit.framework.TestCase;import static com.google.common.base.CaseFormat.*;public class CaseFormatTest extends TestCase {public void testIdentity() {for (CaseFormat from : CaseFormat.values()) {assertSame(from + " to " + from, "foo", from.to(from, "foo"));for (CaseFormat to : CaseFormat.values()) {assertEquals(from + " to " + to, "", from.to(to, ""));assertEquals(from + " to " + to, " ", from.to(to, " "));}}}@GwtIncompatible // NullPointerTesterpublic void testNullArguments() {NullPointerTester tester = new NullPointerTester();tester.testAllPublicStaticMethods(CaseFormat.class);for (CaseFormat format : CaseFormat.values()) {tester.testAllPublicInstanceMethods(format);}}public void testLowerHyphenToLowerHyphen() {assertEquals("foo", LOWER_HYPHEN.to(LOWER_HYPHEN, "foo"));assertEquals("foo-bar", LOWER_HYPHEN.to(LOWER_HYPHEN, "foo-bar"));}public void testLowerHyphenToLowerUnderscore() {assertEquals("foo", LOWER_HYPHEN.to(LOWER_UNDERSCORE, "foo"));assertEquals("foo_bar", LOWER_HYPHEN.to(LOWER_UNDERSCORE, "foo-bar"));}public void testLowerHyphenToLowerCamel() {assertEquals("foo", LOWER_HYPHEN.to(LOWER_CAMEL, "foo"));assertEquals("fooBar", LOWER_HYPHEN.to(LOWER_CAMEL, "foo-bar"));}public void testLowerHyphenToUpperCamel() {assertEquals("Foo", LOWER_HYPHEN.to(UPPER_CAMEL, "foo"));assertEquals("FooBar", LOWER_HYPHEN.to(UPPER_CAMEL, "foo-bar"));}public void testLowerHyphenToUpperUnderscore() {assertEquals("FOO", LOWER_HYPHEN.to(UPPER_UNDERSCORE, "foo"));assertEquals("FOO_BAR", LOWER_HYPHEN.to(UPPER_UNDERSCORE, "foo-bar"));}public void testLowerUnderscoreToLowerHyphen() {assertEquals("foo", LOWER_UNDERSCORE.to(LOWER_HYPHEN, "foo"));assertEquals("foo-bar", LOWER_UNDERSCORE.to(LOWER_HYPHEN, "foo_bar"));}public void testLowerUnderscoreToLowerUnderscore() {assertEquals("foo", LOWER_UNDERSCORE.to(LOWER_UNDERSCORE, "foo"));assertEquals("foo_bar", LOWER_UNDERSCORE.to(LOWER_UNDERSCORE, "foo_bar"));}public void testLowerUnderscoreToLowerCamel() {assertEquals("foo", LOWER_UNDERSCORE.to(LOWER_CAMEL, "foo"));assertEquals("fooBar", LOWER_UNDERSCORE.to(LOWER_CAMEL, "foo_bar"));}public void testLowerUnderscoreToUpperCamel() {assertEquals("Foo", LOWER_UNDERSCORE.to(UPPER_CAMEL, "foo"));assertEquals("FooBar", LOWER_UNDERSCORE.to(UPPER_CAMEL, "foo_bar"));}public void testLowerUnderscoreToUpperUnderscore() {assertEquals("FOO", LOWER_UNDERSCORE.to(UPPER_UNDERSCORE, "foo"));assertEquals("FOO_BAR", LOWER_UNDERSCORE.to(UPPER_UNDERSCORE, "foo_bar"));}public void testLowerCamelToLowerHyphen() {assertEquals("foo", LOWER_CAMEL.to(LOWER_HYPHEN, "foo"));assertEquals("foo-bar", LOWER_CAMEL.to(LOWER_HYPHEN, "fooBar"));assertEquals("h-t-t-p", LOWER_CAMEL.to(LOWER_HYPHEN, "HTTP"));}public void testLowerCamelToLowerUnderscore() {assertEquals("foo", LOWER_CAMEL.to(LOWER_UNDERSCORE, "foo"));assertEquals("foo_bar", LOWER_CAMEL.to(LOWER_UNDERSCORE, "fooBar"));assertEquals("h_t_t_p", LOWER_CAMEL.to(LOWER_UNDERSCORE, "hTTP"));}public void testLowerCamelToLowerCamel() {assertEquals("foo", LOWER_CAMEL.to(LOWER_CAMEL, "foo"));assertEquals("fooBar", LOWER_CAMEL.to(LOWER_CAMEL, "fooBar"));}public void testLowerCamelToUpperCamel() {assertEquals("Foo", LOWER_CAMEL.to(UPPER_CAMEL, "foo"));assertEquals("FooBar", LOWER_CAMEL.to(UPPER_CAMEL, "fooBar"));assertEquals("HTTP", LOWER_CAMEL.to(UPPER_CAMEL, "hTTP"));}public void testLowerCamelToUpperUnderscore() {assertEquals("FOO", LOWER_CAMEL.to(UPPER_UNDERSCORE, "foo"));assertEquals("FOO_BAR", LOWER_CAMEL.to(UPPER_UNDERSCORE, "fooBar"));}public void testUpperCamelToLowerHyphen() {assertEquals("foo", UPPER_CAMEL.to(LOWER_HYPHEN, "Foo"));assertEquals("foo-bar", UPPER_CAMEL.to(LOWER_HYPHEN, "FooBar"));}public void testUpperCamelToLowerUnderscore() {assertEquals("foo", UPPER_CAMEL.to(LOWER_UNDERSCORE, "Foo"));assertEquals("foo_bar", UPPER_CAMEL.to(LOWER_UNDERSCORE, "FooBar"));}public void testUpperCamelToLowerCamel() {assertEquals("foo", UPPER_CAMEL.to(LOWER_CAMEL, "Foo"));assertEquals("fooBar", UPPER_CAMEL.to(LOWER_CAMEL, "FooBar"));assertEquals("hTTP", UPPER_CAMEL.to(LOWER_CAMEL, "HTTP"));}public void testUpperCamelToUpperCamel() {assertEquals("Foo", UPPER_CAMEL.to(UPPER_CAMEL, "Foo"));assertEquals("FooBar", UPPER_CAMEL.to(UPPER_CAMEL, "FooBar"));}public void testUpperCamelToUpperUnderscore() {assertEquals("FOO", UPPER_CAMEL.to(UPPER_UNDERSCORE, "Foo"));assertEquals("FOO_BAR", UPPER_CAMEL.to(UPPER_UNDERSCORE, "FooBar"));assertEquals("H_T_T_P", UPPER_CAMEL.to(UPPER_UNDERSCORE, "HTTP"));assertEquals("H__T__T__P", UPPER_CAMEL.to(UPPER_UNDERSCORE, "H_T_T_P"));}public void testUpperUnderscoreToLowerHyphen() {assertEquals("foo", UPPER_UNDERSCORE.to(LOWER_HYPHEN, "FOO"));assertEquals("foo-bar", UPPER_UNDERSCORE.to(LOWER_HYPHEN, "FOO_BAR"));}public void testUpperUnderscoreToLowerUnderscore() {assertEquals("foo", UPPER_UNDERSCORE.to(LOWER_UNDERSCORE, "FOO"));assertEquals("foo_bar", UPPER_UNDERSCORE.to(LOWER_UNDERSCORE, "FOO_BAR"));}public void testUpperUnderscoreToLowerCamel() {assertEquals("foo", UPPER_UNDERSCORE.to(LOWER_CAMEL, "FOO"));assertEquals("fooBar", UPPER_UNDERSCORE.to(LOWER_CAMEL, "FOO_BAR"));}public void testUpperUnderscoreToUpperCamel() {assertEquals("Foo", UPPER_UNDERSCORE.to(UPPER_CAMEL, "FOO"));assertEquals("FooBar", UPPER_UNDERSCORE.to(UPPER_CAMEL, "FOO_BAR"));assertEquals("HTTP", UPPER_UNDERSCORE.to(UPPER_CAMEL, "H_T_T_P"));}public void testUpperUnderscoreToUpperUnderscore() {assertEquals("FOO", UPPER_UNDERSCORE.to(UPPER_UNDERSCORE, "FOO"));assertEquals("FOO_BAR", UPPER_UNDERSCORE.to(UPPER_UNDERSCORE, "FOO_BAR"));}public void testConverterToForward() {assertEquals("FooBar", UPPER_UNDERSCORE.converterTo(UPPER_CAMEL).convert("FOO_BAR"));assertEquals("fooBar", UPPER_UNDERSCORE.converterTo(LOWER_CAMEL).convert("FOO_BAR"));assertEquals("FOO_BAR", UPPER_CAMEL.converterTo(UPPER_UNDERSCORE).convert("FooBar"));assertEquals("FOO_BAR", LOWER_CAMEL.converterTo(UPPER_UNDERSCORE).convert("fooBar"));}public void testConverterToBackward() {assertEquals("FOO_BAR", UPPER_UNDERSCORE.converterTo(UPPER_CAMEL).reverse().convert("FooBar"));assertEquals("FOO_BAR", UPPER_UNDERSCORE.converterTo(LOWER_CAMEL).reverse().convert("fooBar"));assertEquals("FooBar", UPPER_CAMEL.converterTo(UPPER_UNDERSCORE).reverse().convert("FOO_BAR"));assertEquals("fooBar", LOWER_CAMEL.converterTo(UPPER_UNDERSCORE).reverse().convert("FOO_BAR"));}public void testConverter_nullConversions() {for (CaseFormat outer : CaseFormat.values()) {for (CaseFormat inner : CaseFormat.values()) {assertNull(outer.converterTo(inner).convert(null));assertNull(outer.converterTo(inner).reverse().convert(null));}}}public void testConverter_toString() {assertEquals("LOWER_HYPHEN.converterTo(UPPER_CAMEL)", LOWER_HYPHEN.converterTo(UPPER_CAMEL).toString());}public void testConverter_serialization() {for (CaseFormat outer : CaseFormat.values()) {for (CaseFormat inner : CaseFormat.values()) {SerializableTester.reserializeAndAssert(outer.converterTo(inner));}}}}

3.CharMatcher字符匹配器

确定任何Java中char值是真还是假,就像Predicate对任何Object所做的一样。还提供了基于此函数的基本文本处理方法。强烈建议实现的过程必须无副作用且不可变。

在此类的整个文档中,短语“匹配字符”用于表示"任何charc,其中this.matches(c)返回true"。

警告: 此类仅处理char值,即BMP字符。它不理解0x100000x10FFFF范围内的补充Unicode代码点,该范围包括大多数分配的字符,包括重要的CJK字符和表情符号。

补充字符使用代理对编码为String,而CharMatcher将这些字符视为两个单独的字符。 countIn将每个补充字符计为2个chars。

对于最新的Unicode字符属性(数字,字母等)并支持补充代码点,请使用ICU4J UCharacterUnicodeSet(构建后为freeze())。对于基于UnicodeSet的基本文本处理,请使用ICU4J UnicodeSetSpanner

使用示例:

String trimmed = whitespace().trimFrom(userInput);
if (ascii().matchesAllOf(s)) { ... }

在过去,我们的StringUtil类不受控制地增长,并且具有许多类似这样的方法:
allAsciicollapsecollapseControlCharscollapseWhitespacelastIndexNotOfnumSharedCharsremoveCharsremoveCrLfretainAllCharsstripstripAndCollapsestripNonDigits

它们代表两个概念的部分交叉:

  1. 什么构成“匹配”字符?
  2. 如何处理这些“匹配”的字符?

为了简化这一难题,开发了CharMatcher

直观地,可以将CharMatcher视为代表特定类别的字符,例如数字或空格。实际上,CharMatcher只是有关字符的布尔谓词——事实上,CharMatcher实现了[Predicate<Character>]——但是由于引用“所有空白字符”或“所有小写字母”太普遍了,因此Guava提供了专门的字符语法和API。

但是CharMatcher的实用工具包含在操作中,它使你可以在出现指定类别的字符时执行:修剪[trimming],折叠[collapsing],移除[removing],保留[retaining]等等。CharMatcher类型的对象表示概念1:什么构成匹配字符?然后,它提供了许多回答概念2的操作:如何处理这些匹配的字符?结果是,API复杂度呈线性增加,而灵活性和功能则成倍增加。好极了!

String noControl = CharMatcher.javaIsoControl().removeFrom(string); // remove control characters
String theDigits = CharMatcher.digit().retainFrom(string); // only the digits
String spaced = CharMatcher.whitespace().trimAndCollapseFrom(string, ' ');// trim whitespace at ends, and replace/collapse whitespace into single spaces
String noDigits = CharMatcher.javaDigit().replaceFrom(string, "*"); // star out all digits
String lowerAndDigit = CharMatcher.javaDigit().or(CharMatcher.javaLowerCase()).retainFrom(string);// eliminate all characters that aren't digits or lowercase

注意:CharMatcher仅处理char值;它不能理解0x100000x10FFFF范围内的补充Unicode代码点。使用代理对将此类逻辑字符编码为String,并且CharMatcher将这些字符视为两个单独的字符。

3.1获取字符匹配器

提供的CharMatcher工厂方法可以满足许多需求:

  • any()
  • none()
  • whitespace()
  • breakingWhitespace()
  • invisible()
  • digit()
  • javaLetter()
  • javaDigit()
  • javaLetterOrDigit()
  • javaIsoControl()
  • javaLowerCase()
  • javaUpperCase()
  • ascii()
  • singleWidth()

获取CharMatcher的其它常见方法包括:

方法 描述
anyOf(CharSequence) 指定希望匹配的所有字符。例如,CharMatcher.anyOf("aeiou")匹配小写英语元音。
is(char) 仅指定一个字符进行匹配。
inRange(char, char) 指定要匹配的字符范围,示例:CharMatcher.inRange('a', 'z')

此外,CharMatcher具有negate()and(CharMatcher)or(CharMatcher)。这些在CharMatcher上提供了简单的布尔操作。

3.2使用字符匹配器

CharMatcher提供了多种多样方法来处理任何CharSequence中出现的指定字符。提供的方法比我们在此处列出的方法更多,但是一些最常用的方法是:

方法 描述
collapseFrom(CharSequence, char) 将每组连续匹配的字符替换为指定的字符。例如,WHITESPACE.collapseFrom(string, ' ')将空格折叠为单个空格。
matchesAllOf(CharSequence) 测试此匹配器是否匹配序列中的所有字符。例如,ASCII.matchesAllOf(string)测试字符串中的所有字符是否均为ASCII。
removeFrom(CharSequence) 从序列中删除匹配的字符。
retainFrom(CharSequence) 从序列中删除所有不匹配的字符。
trimFrom(CharSequence) 删除开头和结尾的匹配字符。
replaceFrom(CharSequence, CharSequence) 用给定的序列替换匹配的字符。

(注意:所有这些方法都返回一个String,但matchesAllOf除外,后者返回一个boolean布尔值。)

3.3使用示例

import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.CharMatcher;
import com.google.common.base.Predicates;
import com.google.common.base.Strings;
import com.google.common.testing.NullPointerTester;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import static com.google.common.base.CharMatcher.*;public class CharMatcherTest extends TestCase {@GwtIncompatible // NullPointerTesterpublic void testStaticNullPointers() throws Exception {NullPointerTester tester = new NullPointerTester();tester.testAllPublicStaticMethods(CharMatcher.class);tester.testAllPublicInstanceMethods(CharMatcher.any());tester.testAllPublicInstanceMethods(anyOf("abc"));}private static final CharMatcher WHATEVER =new CharMatcher() {@Overridepublic boolean matches(char c) {throw new AssertionFailedError("You weren't supposed to actually invoke me!");}};public void testAnyAndNone_logicalOps() throws Exception {// These are testing behavior that's never promised by the API, but since// we're lucky enough that these do pass, it saves us from having to write// more excruciating tests! Hooray!assertSame(CharMatcher.any(), CharMatcher.none().negate());assertSame(CharMatcher.none(), CharMatcher.any().negate());assertSame(WHATEVER, CharMatcher.any().and(WHATEVER));assertSame(CharMatcher.any(), CharMatcher.any().or(WHATEVER));assertSame(CharMatcher.none(), CharMatcher.none().and(WHATEVER));assertSame(WHATEVER, CharMatcher.none().or(WHATEVER));}// The rest of the behavior of ANY and DEFAULT will be covered in the tests for// the text processing methods below.public void testWhitespaceBreakingWhitespaceSubset() throws Exception {for (int c = 0; c <= Character.MAX_VALUE; c++) {if (breakingWhitespace().matches((char) c)) {assertTrue(Integer.toHexString(c), whitespace().matches((char) c));}}}// The next tests require ICU4J and have, at least for now, been sliced out// of the open-source view of the tests.@GwtIncompatible // Character.isISOControlpublic void testJavaIsoControl() {for (int c = 0; c <= Character.MAX_VALUE; c++) {assertEquals("" + c, Character.isISOControl(c), CharMatcher.javaIsoControl().matches((char) c));}}// Omitting tests for the rest of the JAVA_* constants as these are defined// as extremely straightforward pass-throughs to the JDK methods.// We're testing the is(), isNot(), anyOf(), noneOf() and inRange() methods// below by testing their text-processing methods.// The organization of this test class is unusual, as it's not done by// method, but by overall "scenario". Also, the variety of actual tests we// do borders on absurd overkill. Better safe than sorry, though?public void testEmpty() throws Exception {doTestEmpty(CharMatcher.any());doTestEmpty(CharMatcher.none());doTestEmpty(is('a'));doTestEmpty(isNot('a'));doTestEmpty(anyOf(""));doTestEmpty(anyOf("x"));doTestEmpty(anyOf("xy"));doTestEmpty(anyOf("CharMatcher"));doTestEmpty(noneOf("CharMatcher"));doTestEmpty(inRange('n', 'q'));doTestEmpty(forPredicate(Predicates.equalTo('c')));}@GwtIncompatible // NullPointerTesterpublic void testNull() throws Exception {doTestNull(CharMatcher.any());doTestNull(CharMatcher.none());doTestNull(is('a'));doTestNull(isNot('a'));doTestNull(anyOf(""));doTestNull(anyOf("x"));doTestNull(anyOf("xy"));doTestNull(anyOf("CharMatcher"));doTestNull(noneOf("CharMatcher"));doTestNull(inRange('n', 'q'));doTestNull(forPredicate(Predicates.equalTo('c')));}private void doTestEmpty(CharMatcher matcher) throws Exception {reallyTestEmpty(matcher);reallyTestEmpty(matcher.negate());reallyTestEmpty(matcher.precomputed());}private void reallyTestEmpty(CharMatcher matcher) throws Exception {assertEquals(-1, matcher.indexIn(""));assertEquals(-1, matcher.indexIn("", 0));try {matcher.indexIn("", 1);fail();} catch (IndexOutOfBoundsException expected) {}try {matcher.indexIn("", -1);fail();} catch (IndexOutOfBoundsException expected) {}assertEquals(-1, matcher.lastIndexIn(""));assertFalse(matcher.matchesAnyOf(""));assertTrue(matcher.matchesAllOf(""));assertTrue(matcher.matchesNoneOf(""));assertEquals("", matcher.removeFrom(""));assertEquals("", matcher.replaceFrom("", 'z'));assertEquals("", matcher.replaceFrom("", "ZZ"));assertEquals("", matcher.trimFrom(""));assertEquals(0, matcher.countIn(""));}@GwtIncompatible // NullPointerTesterprivate static void doTestNull(CharMatcher matcher) throws Exception {NullPointerTester tester = new NullPointerTester();tester.testAllPublicInstanceMethods(matcher);}public void testNoMatches() {doTestNoMatches(CharMatcher.none(), "blah");doTestNoMatches(is('a'), "bcde");doTestNoMatches(isNot('a'), "aaaa");doTestNoMatches(anyOf(""), "abcd");doTestNoMatches(anyOf("x"), "abcd");doTestNoMatches(anyOf("xy"), "abcd");doTestNoMatches(anyOf("CharMatcher"), "zxqy");doTestNoMatches(noneOf("CharMatcher"), "ChMa");doTestNoMatches(inRange('p', 'x'), "mom");doTestNoMatches(forPredicate(Predicates.equalTo('c')), "abe");doTestNoMatches(inRange('A', 'Z').and(inRange('F', 'K').negate()), "F1a");doTestNoMatches(CharMatcher.digit(), "\tAz()");doTestNoMatches(CharMatcher.javaDigit(), "\tAz()");doTestNoMatches(CharMatcher.digit().and(CharMatcher.ascii()), "\tAz()");doTestNoMatches(CharMatcher.singleWidth(), "\u05bf\u3000");}private void doTestNoMatches(CharMatcher matcher, String s) {reallyTestNoMatches(matcher, s);reallyTestAllMatches(matcher.negate(), s);reallyTestNoMatches(matcher.precomputed(), s);reallyTestAllMatches(matcher.negate().precomputed(), s);reallyTestAllMatches(matcher.precomputed().negate(), s);reallyTestNoMatches(forPredicate(matcher), s);reallyTestNoMatches(matcher, new StringBuilder(s));}public void testAllMatches() {doTestAllMatches(CharMatcher.any(), "blah");doTestAllMatches(isNot('a'), "bcde");doTestAllMatches(is('a'), "aaaa");doTestAllMatches(noneOf("CharMatcher"), "zxqy");doTestAllMatches(anyOf("x"), "xxxx");doTestAllMatches(anyOf("xy"), "xyyx");doTestAllMatches(anyOf("CharMatcher"), "ChMa");doTestAllMatches(inRange('m', 'p'), "mom");doTestAllMatches(forPredicate(Predicates.equalTo('c')), "ccc");doTestAllMatches(CharMatcher.digit(), "0123456789\u0ED0\u1B59");doTestAllMatches(CharMatcher.javaDigit(), "0123456789");doTestAllMatches(CharMatcher.digit().and(CharMatcher.ascii()), "0123456789");doTestAllMatches(CharMatcher.singleWidth(), "\t0123ABCdef~\u00A0\u2111");}private void doTestAllMatches(CharMatcher matcher, String s) {reallyTestAllMatches(matcher, s);reallyTestNoMatches(matcher.negate(), s);reallyTestAllMatches(matcher.precomputed(), s);reallyTestNoMatches(matcher.negate().precomputed(), s);reallyTestNoMatches(matcher.precomputed().negate(), s);reallyTestAllMatches(forPredicate(matcher), s);reallyTestAllMatches(matcher, new StringBuilder(s));}private void reallyTestNoMatches(CharMatcher matcher, CharSequence s) {assertFalse(matcher.matches(s.charAt(0)));assertEquals(-1, matcher.indexIn(s));assertEquals(-1, matcher.indexIn(s, 0));assertEquals(-1, matcher.indexIn(s, 1));assertEquals(-1, matcher.indexIn(s, s.length()));try {matcher.indexIn(s, s.length() + 1);fail();} catch (IndexOutOfBoundsException expected) {}try {matcher.indexIn(s, -1);fail();} catch (IndexOutOfBoundsException expected) {}assertEquals(-1, matcher.lastIndexIn(s));assertFalse(matcher.matchesAnyOf(s));assertFalse(matcher.matchesAllOf(s));assertTrue(matcher.matchesNoneOf(s));assertEquals(s.toString(), matcher.removeFrom(s));assertEquals(s.toString(), matcher.replaceFrom(s, 'z'));assertEquals(s.toString(), matcher.replaceFrom(s, "ZZ"));assertEquals(s.toString(), matcher.trimFrom(s));assertEquals(0, matcher.countIn(s));}private void reallyTestAllMatches(CharMatcher matcher, CharSequence s) {assertTrue(matcher.matches(s.charAt(0)));assertEquals(0, matcher.indexIn(s));assertEquals(0, matcher.indexIn(s, 0));assertEquals(1, matcher.indexIn(s, 1));assertEquals(-1, matcher.indexIn(s, s.length()));assertEquals(s.length() - 1, matcher.lastIndexIn(s));assertTrue(matcher.matchesAnyOf(s));assertTrue(matcher.matchesAllOf(s));assertFalse(matcher.matchesNoneOf(s));assertEquals("", matcher.removeFrom(s));assertEquals(Strings.repeat("z", s.length()), matcher.replaceFrom(s, 'z'));assertEquals(Strings.repeat("ZZ", s.length()), matcher.replaceFrom(s, "ZZ"));assertEquals("", matcher.trimFrom(s));assertEquals(s.length(), matcher.countIn(s));}public void testGeneral() {doTestGeneral(is('a'), 'a', 'b');doTestGeneral(isNot('a'), 'b', 'a');doTestGeneral(anyOf("x"), 'x', 'z');doTestGeneral(anyOf("xy"), 'y', 'z');doTestGeneral(anyOf("CharMatcher"), 'C', 'z');doTestGeneral(noneOf("CharMatcher"), 'z', 'C');doTestGeneral(inRange('p', 'x'), 'q', 'z');}private void doTestGeneral(CharMatcher matcher, char match, char noMatch) {doTestOneCharMatch(matcher, "" + match);doTestOneCharNoMatch(matcher, "" + noMatch);doTestMatchThenNoMatch(matcher, "" + match + noMatch);doTestNoMatchThenMatch(matcher, "" + noMatch + match);}private void doTestOneCharMatch(CharMatcher matcher, String s) {reallyTestOneCharMatch(matcher, s);reallyTestOneCharNoMatch(matcher.negate(), s);reallyTestOneCharMatch(matcher.precomputed(), s);reallyTestOneCharNoMatch(matcher.negate().precomputed(), s);reallyTestOneCharNoMatch(matcher.precomputed().negate(), s);}private void doTestOneCharNoMatch(CharMatcher matcher, String s) {reallyTestOneCharNoMatch(matcher, s);reallyTestOneCharMatch(matcher.negate(), s);reallyTestOneCharNoMatch(matcher.precomputed(), s);reallyTestOneCharMatch(matcher.negate().precomputed(), s);reallyTestOneCharMatch(matcher.precomputed().negate(), s);}private void doTestMatchThenNoMatch(CharMatcher matcher, String s) {reallyTestMatchThenNoMatch(matcher, s);reallyTestNoMatchThenMatch(matcher.negate(), s);reallyTestMatchThenNoMatch(matcher.precomputed(), s);reallyTestNoMatchThenMatch(matcher.negate().precomputed(), s);reallyTestNoMatchThenMatch(matcher.precomputed().negate(), s);}private void doTestNoMatchThenMatch(CharMatcher matcher, String s) {reallyTestNoMatchThenMatch(matcher, s);reallyTestMatchThenNoMatch(matcher.negate(), s);reallyTestNoMatchThenMatch(matcher.precomputed(), s);reallyTestMatchThenNoMatch(matcher.negate().precomputed(), s);reallyTestMatchThenNoMatch(matcher.precomputed().negate(), s);}@SuppressWarnings("deprecation") // intentionally testing apply() methodprivate void reallyTestOneCharMatch(CharMatcher matcher, String s) {assertTrue(matcher.matches(s.charAt(0)));assertTrue(matcher.apply(s.charAt(0)));assertEquals(0, matcher.indexIn(s));assertEquals(0, matcher.indexIn(s, 0));assertEquals(-1, matcher.indexIn(s, 1));assertEquals(0, matcher.lastIndexIn(s));assertTrue(matcher.matchesAnyOf(s));assertTrue(matcher.matchesAllOf(s));assertFalse(matcher.matchesNoneOf(s));assertEquals("", matcher.removeFrom(s));assertEquals("z", matcher.replaceFrom(s, 'z'));assertEquals("ZZ", matcher.replaceFrom(s, "ZZ"));assertEquals("", matcher.trimFrom(s));assertEquals(1, matcher.countIn(s));}@SuppressWarnings("deprecation") // intentionally testing apply() methodprivate void reallyTestOneCharNoMatch(CharMatcher matcher, String s) {assertFalse(matcher.matches(s.charAt(0)));assertFalse(matcher.apply(s.charAt(0)));assertEquals(-1, matcher.indexIn(s));assertEquals(-1, matcher.indexIn(s, 0));assertEquals(-1, matcher.indexIn(s, 1));assertEquals(-1, matcher.lastIndexIn(s));assertFalse(matcher.matchesAnyOf(s));assertFalse(matcher.matchesAllOf(s));assertTrue(matcher.matchesNoneOf(s));assertSame(s, matcher.removeFrom(s));assertSame(s, matcher.replaceFrom(s, 'z'));assertSame(s, matcher.replaceFrom(s, "ZZ"));assertSame(s, matcher.trimFrom(s));assertSame(0, matcher.countIn(s));}private void reallyTestMatchThenNoMatch(CharMatcher matcher, String s) {assertEquals(0, matcher.indexIn(s));assertEquals(0, matcher.indexIn(s, 0));assertEquals(-1, matcher.indexIn(s, 1));assertEquals(-1, matcher.indexIn(s, 2));assertEquals(0, matcher.lastIndexIn(s));assertTrue(matcher.matchesAnyOf(s));assertFalse(matcher.matchesAllOf(s));assertFalse(matcher.matchesNoneOf(s));assertEquals(s.substring(1), matcher.removeFrom(s));assertEquals("z" + s.substring(1), matcher.replaceFrom(s, 'z'));assertEquals("ZZ" + s.substring(1), matcher.replaceFrom(s, "ZZ"));assertEquals(s.substring(1), matcher.trimFrom(s));assertEquals(1, matcher.countIn(s));}private void reallyTestNoMatchThenMatch(CharMatcher matcher, String s) {assertEquals(1, matcher.indexIn(s));assertEquals(1, matcher.indexIn(s, 0));assertEquals(1, matcher.indexIn(s, 1));assertEquals(-1, matcher.indexIn(s, 2));assertEquals(1, matcher.lastIndexIn(s));assertTrue(matcher.matchesAnyOf(s));assertFalse(matcher.matchesAllOf(s));assertFalse(matcher.matchesNoneOf(s));assertEquals(s.substring(0, 1), matcher.removeFrom(s));assertEquals(s.substring(0, 1) + "z", matcher.replaceFrom(s, 'z'));assertEquals(s.substring(0, 1) + "ZZ", matcher.replaceFrom(s, "ZZ"));assertEquals(s.substring(0, 1), matcher.trimFrom(s));assertEquals(1, matcher.countIn(s));}/*** Checks that expected is equals to out, and further, if in is equals to expected, then out is* successfully optimized to be identical to in, i.e. that "in" is simply returned.*/private void assertEqualsSame(String expected, String in, String out) {if (expected.equals(in)) {assertSame(in, out);} else {assertEquals(expected, out);}}// Test collapse() a little differently than the rest, as we really want to// cover lots of different configurations of input textpublic void testCollapse() {// collapsing groups of '-' into '_' or '-'doTestCollapse("-", "_");doTestCollapse("x-", "x_");doTestCollapse("-x", "_x");doTestCollapse("--", "_");doTestCollapse("x--", "x_");doTestCollapse("--x", "_x");doTestCollapse("-x-", "_x_");doTestCollapse("x-x", "x_x");doTestCollapse("---", "_");doTestCollapse("--x-", "_x_");doTestCollapse("--xx", "_xx");doTestCollapse("-x--", "_x_");doTestCollapse("-x-x", "_x_x");doTestCollapse("-xx-", "_xx_");doTestCollapse("x--x", "x_x");doTestCollapse("x-x-", "x_x_");doTestCollapse("x-xx", "x_xx");doTestCollapse("x-x--xx---x----x", "x_x_xx_x_x");doTestCollapseWithNoChange("");doTestCollapseWithNoChange("x");doTestCollapseWithNoChange("xx");}private void doTestCollapse(String in, String out) {// Try a few different matchers which all match '-' and not 'x'// Try replacement chars that both do and do not change the value.for (char replacement : new char[]{'_', '-'}) {String expected = out.replace('_', replacement);assertEqualsSame(expected, in, is('-').collapseFrom(in, replacement));assertEqualsSame(expected, in, is('-').collapseFrom(in, replacement));assertEqualsSame(expected, in, is('-').or(is('#')).collapseFrom(in, replacement));assertEqualsSame(expected, in, isNot('x').collapseFrom(in, replacement));assertEqualsSame(expected, in, is('x').negate().collapseFrom(in, replacement));assertEqualsSame(expected, in, anyOf("-").collapseFrom(in, replacement));assertEqualsSame(expected, in, anyOf("-#").collapseFrom(in, replacement));assertEqualsSame(expected, in, anyOf("-#123").collapseFrom(in, replacement));}}private void doTestCollapseWithNoChange(String inout) {assertSame(inout, is('-').collapseFrom(inout, '_'));assertSame(inout, is('-').or(is('#')).collapseFrom(inout, '_'));assertSame(inout, isNot('x').collapseFrom(inout, '_'));assertSame(inout, is('x').negate().collapseFrom(inout, '_'));assertSame(inout, anyOf("-").collapseFrom(inout, '_'));assertSame(inout, anyOf("-#").collapseFrom(inout, '_'));assertSame(inout, anyOf("-#123").collapseFrom(inout, '_'));assertSame(inout, CharMatcher.none().collapseFrom(inout, '_'));}public void testCollapse_any() {assertEquals("", CharMatcher.any().collapseFrom("", '_'));assertEquals("_", CharMatcher.any().collapseFrom("a", '_'));assertEquals("_", CharMatcher.any().collapseFrom("ab", '_'));assertEquals("_", CharMatcher.any().collapseFrom("abcd", '_'));}public void testTrimFrom() {// trimming -doTestTrimFrom("-", "");doTestTrimFrom("x-", "x");doTestTrimFrom("-x", "x");doTestTrimFrom("--", "");doTestTrimFrom("x--", "x");doTestTrimFrom("--x", "x");doTestTrimFrom("-x-", "x");doTestTrimFrom("x-x", "x-x");doTestTrimFrom("---", "");doTestTrimFrom("--x-", "x");doTestTrimFrom("--xx", "xx");doTestTrimFrom("-x--", "x");doTestTrimFrom("-x-x", "x-x");doTestTrimFrom("-xx-", "xx");doTestTrimFrom("x--x", "x--x");doTestTrimFrom("x-x-", "x-x");doTestTrimFrom("x-xx", "x-xx");doTestTrimFrom("x-x--xx---x----x", "x-x--xx---x----x");// additional testing using the doc exampleassertEquals("cat", anyOf("ab").trimFrom("abacatbab"));}private void doTestTrimFrom(String in, String out) {// Try a few different matchers which all match '-' and not 'x'assertEquals(out, is('-').trimFrom(in));assertEquals(out, is('-').or(is('#')).trimFrom(in));assertEquals(out, isNot('x').trimFrom(in));assertEquals(out, is('x').negate().trimFrom(in));assertEquals(out, anyOf("-").trimFrom(in));assertEquals(out, anyOf("-#").trimFrom(in));assertEquals(out, anyOf("-#123").trimFrom(in));}public void testTrimLeadingFrom() {// trimming -doTestTrimLeadingFrom("-", "");doTestTrimLeadingFrom("x-", "x-");doTestTrimLeadingFrom("-x", "x");doTestTrimLeadingFrom("--", "");doTestTrimLeadingFrom("x--", "x--");doTestTrimLeadingFrom("--x", "x");doTestTrimLeadingFrom("-x-", "x-");doTestTrimLeadingFrom("x-x", "x-x");doTestTrimLeadingFrom("---", "");doTestTrimLeadingFrom("--x-", "x-");doTestTrimLeadingFrom("--xx", "xx");doTestTrimLeadingFrom("-x--", "x--");doTestTrimLeadingFrom("-x-x", "x-x");doTestTrimLeadingFrom("-xx-", "xx-");doTestTrimLeadingFrom("x--x", "x--x");doTestTrimLeadingFrom("x-x-", "x-x-");doTestTrimLeadingFrom("x-xx", "x-xx");doTestTrimLeadingFrom("x-x--xx---x----x", "x-x--xx---x----x");// additional testing using the doc exampleassertEquals("catbab", anyOf("ab").trimLeadingFrom("abacatbab"));}private void doTestTrimLeadingFrom(String in, String out) {// Try a few different matchers which all match '-' and not 'x'assertEquals(out, is('-').trimLeadingFrom(in));assertEquals(out, is('-').or(is('#')).trimLeadingFrom(in));assertEquals(out, isNot('x').trimLeadingFrom(in));assertEquals(out, is('x').negate().trimLeadingFrom(in));assertEquals(out, anyOf("-#").trimLeadingFrom(in));assertEquals(out, anyOf("-#123").trimLeadingFrom(in));}public void testTrimTrailingFrom() {// trimming -doTestTrimTrailingFrom("-", "");doTestTrimTrailingFrom("x-", "x");doTestTrimTrailingFrom("-x", "-x");doTestTrimTrailingFrom("--", "");doTestTrimTrailingFrom("x--", "x");doTestTrimTrailingFrom("--x", "--x");doTestTrimTrailingFrom("-x-", "-x");doTestTrimTrailingFrom("x-x", "x-x");doTestTrimTrailingFrom("---", "");doTestTrimTrailingFrom("--x-", "--x");doTestTrimTrailingFrom("--xx", "--xx");doTestTrimTrailingFrom("-x--", "-x");doTestTrimTrailingFrom("-x-x", "-x-x");doTestTrimTrailingFrom("-xx-", "-xx");doTestTrimTrailingFrom("x--x", "x--x");doTestTrimTrailingFrom("x-x-", "x-x");doTestTrimTrailingFrom("x-xx", "x-xx");doTestTrimTrailingFrom("x-x--xx---x----x", "x-x--xx---x----x");// additional testing using the doc exampleassertEquals("abacat", anyOf("ab").trimTrailingFrom("abacatbab"));}private void doTestTrimTrailingFrom(String in, String out) {// Try a few different matchers which all match '-' and not 'x'assertEquals(out, is('-').trimTrailingFrom(in));assertEquals(out, is('-').or(is('#')).trimTrailingFrom(in));assertEquals(out, isNot('x').trimTrailingFrom(in));assertEquals(out, is('x').negate().trimTrailingFrom(in));assertEquals(out, anyOf("-#").trimTrailingFrom(in));assertEquals(out, anyOf("-#123").trimTrailingFrom(in));}public void testTrimAndCollapse() {// collapsing groups of '-' into '_' or '-'doTestTrimAndCollapse("", "");doTestTrimAndCollapse("x", "x");doTestTrimAndCollapse("-", "");doTestTrimAndCollapse("x-", "x");doTestTrimAndCollapse("-x", "x");doTestTrimAndCollapse("--", "");doTestTrimAndCollapse("x--", "x");doTestTrimAndCollapse("--x", "x");doTestTrimAndCollapse("-x-", "x");doTestTrimAndCollapse("x-x", "x_x");doTestTrimAndCollapse("---", "");doTestTrimAndCollapse("--x-", "x");doTestTrimAndCollapse("--xx", "xx");doTestTrimAndCollapse("-x--", "x");doTestTrimAndCollapse("-x-x", "x_x");doTestTrimAndCollapse("-xx-", "xx");doTestTrimAndCollapse("x--x", "x_x");doTestTrimAndCollapse("x-x-", "x_x");doTestTrimAndCollapse("x-xx", "x_xx");doTestTrimAndCollapse("x-x--xx---x----x", "x_x_xx_x_x");}private void doTestTrimAndCollapse(String in, String out) {// Try a few different matchers which all match '-' and not 'x'for (char replacement : new char[]{'_', '-'}) {String expected = out.replace('_', replacement);assertEqualsSame(expected, in, is('-').trimAndCollapseFrom(in, replacement));assertEqualsSame(expected, in, is('-').or(is('#')).trimAndCollapseFrom(in, replacement));assertEqualsSame(expected, in, isNot('x').trimAndCollapseFrom(in, replacement));assertEqualsSame(expected, in, is('x').negate().trimAndCollapseFrom(in, replacement));assertEqualsSame(expected, in, anyOf("-").trimAndCollapseFrom(in, replacement));assertEqualsSame(expected, in, anyOf("-#").trimAndCollapseFrom(in, replacement));assertEqualsSame(expected, in, anyOf("-#123").trimAndCollapseFrom(in, replacement));}}public void testReplaceFrom() {assertEquals("yoho", is('a').replaceFrom("yaha", 'o'));assertEquals("yh", is('a').replaceFrom("yaha", ""));assertEquals("yoho", is('a').replaceFrom("yaha", "o"));assertEquals("yoohoo", is('a').replaceFrom("yaha", "oo"));assertEquals("12 &gt; 5", is('>').replaceFrom("12 > 5", "&gt;"));}public void testPrecomputedOptimizations() {// These are testing behavior that's never promised by the API.// Some matchers are so efficient that it is a waste of effort to// build a precomputed version.CharMatcher m1 = is('x');assertSame(m1, m1.precomputed());assertEquals(m1.toString(), m1.precomputed().toString());CharMatcher m2 = anyOf("Az");assertSame(m2, m2.precomputed());assertEquals(m2.toString(), m2.precomputed().toString());CharMatcher m3 = inRange('A', 'Z');assertSame(m3, m3.precomputed());assertEquals(m3.toString(), m3.precomputed().toString());assertSame(CharMatcher.none(), CharMatcher.none().precomputed());assertSame(CharMatcher.any(), CharMatcher.any().precomputed());}public void testToString() {assertToStringWorks("CharMatcher.none()", anyOf(""));assertToStringWorks("CharMatcher.is('\\u0031')", anyOf("1"));assertToStringWorks("CharMatcher.isNot('\\u0031')", isNot('1'));assertToStringWorks("CharMatcher.anyOf(\"\\u0031\\u0032\")", anyOf("12"));assertToStringWorks("CharMatcher.anyOf(\"\\u0031\\u0032\\u0033\")", anyOf("321"));assertToStringWorks("CharMatcher.inRange('\\u0031', '\\u0033')", CharMatcher.inRange('1', '3'));}private static void assertToStringWorks(String expected, CharMatcher matcher) {assertEquals(expected, matcher.toString());assertEquals(expected, matcher.precomputed().toString());assertEquals(expected, matcher.negate().negate().toString());assertEquals(expected, matcher.negate().precomputed().negate().toString());assertEquals(expected, matcher.negate().precomputed().negate().precomputed().toString());}
}

4.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提供了对六个标准Charset实现的常量引用,所有Java平台实现均支持。使用它们而不是通过名称来引用字符集。

(注意:如果使用的是JDK7,则应使用StandardCharsets中的常量。)

4.1使用示例

import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Charsets;
import junit.framework.TestCase;import java.nio.charset.Charset;
import java.util.Arrays;public class CharsetsTest extends TestCase {@GwtIncompatible // Non-UTF-8 Charsetpublic void testUsAscii() {assertEquals(Charset.forName("US-ASCII"), Charsets.US_ASCII);}@GwtIncompatible // Non-UTF-8 Charsetpublic void testIso88591() {assertEquals(Charset.forName("ISO-8859-1"), Charsets.ISO_8859_1);}public void testUtf8() {assertEquals(Charset.forName("UTF-8"), Charsets.UTF_8);}@GwtIncompatible // Non-UTF-8 Charsetpublic void testUtf16be() {assertEquals(Charset.forName("UTF-16BE"), Charsets.UTF_16BE);}@GwtIncompatible // Non-UTF-8 Charsetpublic void testUtf16le() {assertEquals(Charset.forName("UTF-16LE"), Charsets.UTF_16LE);}@GwtIncompatible // Non-UTF-8 Charsetpublic void testUtf16() {assertEquals(Charset.forName("UTF-16"), Charsets.UTF_16);}@GwtIncompatible // Non-UTF-8 Charsetpublic void testWhyUsAsciiIsDangerous() {byte[] b1 = "朝日新聞".getBytes(Charsets.US_ASCII);byte[] b2 = "聞朝日新".getBytes(Charsets.US_ASCII);byte[] b3 = "????".getBytes(Charsets.US_ASCII);byte[] b4 = "ニュース".getBytes(Charsets.US_ASCII);byte[] b5 = "スューー".getBytes(Charsets.US_ASCII);// Assert they are all equal (using the transitive property)assertTrue(Arrays.equals(b1, b2));assertTrue(Arrays.equals(b2, b3));assertTrue(Arrays.equals(b3, b4));assertTrue(Arrays.equals(b4, b5));}
}

5.Joiner连接器

用分隔符将字符串序列连接在一起可能会很棘手——但事实并非如此。如果你的序列包含null,则可能会更加困难。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都是线程安全的,并可用作static final静态最终常量。

5.1使用示例

import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Joiner;
import com.google.common.base.Joiner.MapJoiner;
import com.google.common.collect.*;
import com.google.common.testing.NullPointerTester;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;public class JoinerTest extends TestCase {private static final Joiner J = Joiner.on("-");// <Integer> needed to prevent warning :(private static final Iterable<Integer> ITERABLE_ = Arrays.<Integer>asList();private static final Iterable<Integer> ITERABLE_1 = Arrays.asList(1);private static final Iterable<Integer> ITERABLE_12 = Arrays.asList(1, 2);private static final Iterable<Integer> ITERABLE_123 = Arrays.asList(1, 2, 3);private static final Iterable<Integer> ITERABLE_NULL = Arrays.asList((Integer) null);private static final Iterable<Integer> ITERABLE_NULL_NULL = Arrays.asList((Integer) null, null);private static final Iterable<Integer> ITERABLE_NULL_1 = Arrays.asList(null, 1);private static final Iterable<Integer> ITERABLE_1_NULL = Arrays.asList(1, null);private static final Iterable<Integer> ITERABLE_1_NULL_2 = Arrays.asList(1, null, 2);private static final Iterable<Integer> ITERABLE_FOUR_NULLS =Arrays.asList((Integer) null, null, null, null);public void testNoSpecialNullBehavior() {checkNoOutput(J, ITERABLE_);checkResult(J, ITERABLE_1, "1");checkResult(J, ITERABLE_12, "1-2");checkResult(J, ITERABLE_123, "1-2-3");try {J.join(ITERABLE_NULL);fail();} catch (NullPointerException expected) {}try {J.join(ITERABLE_1_NULL_2);fail();} catch (NullPointerException expected) {}try {J.join(ITERABLE_NULL.iterator());fail();} catch (NullPointerException expected) {}try {J.join(ITERABLE_1_NULL_2.iterator());fail();} catch (NullPointerException expected) {}}public void testOnCharOverride() {Joiner onChar = Joiner.on('-');checkNoOutput(onChar, ITERABLE_);checkResult(onChar, ITERABLE_1, "1");checkResult(onChar, ITERABLE_12, "1-2");checkResult(onChar, ITERABLE_123, "1-2-3");}public void testSkipNulls() {Joiner skipNulls = J.skipNulls();checkNoOutput(skipNulls, ITERABLE_);checkNoOutput(skipNulls, ITERABLE_NULL);checkNoOutput(skipNulls, ITERABLE_NULL_NULL);checkNoOutput(skipNulls, ITERABLE_FOUR_NULLS);checkResult(skipNulls, ITERABLE_1, "1");checkResult(skipNulls, ITERABLE_12, "1-2");checkResult(skipNulls, ITERABLE_123, "1-2-3");checkResult(skipNulls, ITERABLE_NULL_1, "1");checkResult(skipNulls, ITERABLE_1_NULL, "1");checkResult(skipNulls, ITERABLE_1_NULL_2, "1-2");}public void testUseForNull() {Joiner zeroForNull = J.useForNull("0");checkNoOutput(zeroForNull, ITERABLE_);checkResult(zeroForNull, ITERABLE_1, "1");checkResult(zeroForNull, ITERABLE_12, "1-2");checkResult(zeroForNull, ITERABLE_123, "1-2-3");checkResult(zeroForNull, ITERABLE_NULL, "0");checkResult(zeroForNull, ITERABLE_NULL_NULL, "0-0");checkResult(zeroForNull, ITERABLE_NULL_1, "0-1");checkResult(zeroForNull, ITERABLE_1_NULL, "1-0");checkResult(zeroForNull, ITERABLE_1_NULL_2, "1-0-2");checkResult(zeroForNull, ITERABLE_FOUR_NULLS, "0-0-0-0");}private static void checkNoOutput(Joiner joiner, Iterable<Integer> set) {assertEquals("", joiner.join(set));assertEquals("", joiner.join(set.iterator()));Object[] array = Lists.newArrayList(set).toArray(new Integer[0]);assertEquals("", joiner.join(array));StringBuilder sb1FromIterable = new StringBuilder();assertSame(sb1FromIterable, joiner.appendTo(sb1FromIterable, set));assertEquals(0, sb1FromIterable.length());StringBuilder sb1FromIterator = new StringBuilder();assertSame(sb1FromIterator, joiner.appendTo(sb1FromIterator, set));assertEquals(0, sb1FromIterator.length());StringBuilder sb2 = new StringBuilder();assertSame(sb2, joiner.appendTo(sb2, array));assertEquals(0, sb2.length());try {joiner.appendTo(NASTY_APPENDABLE, set);} catch (IOException e) {throw new AssertionError(e);}try {joiner.appendTo(NASTY_APPENDABLE, set.iterator());} catch (IOException e) {throw new AssertionError(e);}try {joiner.appendTo(NASTY_APPENDABLE, array);} catch (IOException e) {throw new AssertionError(e);}}private static final Appendable NASTY_APPENDABLE =new Appendable() {@Overridepublic Appendable append(CharSequence csq) throws IOException {throw new IOException();}@Overridepublic Appendable append(CharSequence csq, int start, int end) throws IOException {throw new IOException();}@Overridepublic Appendable append(char c) throws IOException {throw new IOException();}};private static void checkResult(Joiner joiner, Iterable<Integer> parts, String expected) {assertEquals(expected, joiner.join(parts));assertEquals(expected, joiner.join(parts.iterator()));StringBuilder sb1FromIterable = new StringBuilder().append('x');joiner.appendTo(sb1FromIterable, parts);assertEquals("x" + expected, sb1FromIterable.toString());StringBuilder sb1FromIterator = new StringBuilder().append('x');joiner.appendTo(sb1FromIterator, parts.iterator());assertEquals("x" + expected, sb1FromIterator.toString());Integer[] partsArray = Lists.newArrayList(parts).toArray(new Integer[0]);assertEquals(expected, joiner.join(partsArray));StringBuilder sb2 = new StringBuilder().append('x');joiner.appendTo(sb2, partsArray);assertEquals("x" + expected, sb2.toString());int num = partsArray.length - 2;if (num >= 0) {Object[] rest = new Integer[num];for (int i = 0; i < num; i++) {rest[i] = partsArray[i + 2];}assertEquals(expected, joiner.join(partsArray[0], partsArray[1], rest));StringBuilder sb3 = new StringBuilder().append('x');joiner.appendTo(sb3, partsArray[0], partsArray[1], rest);assertEquals("x" + expected, sb3.toString());}}public void test_useForNull_skipNulls() {Joiner j = Joiner.on("x").useForNull("y");try {j = j.skipNulls();fail();} catch (UnsupportedOperationException expected) {}}public void test_skipNulls_useForNull() {Joiner j = Joiner.on("x").skipNulls();try {j = j.useForNull("y");fail();} catch (UnsupportedOperationException expected) {}}public void test_useForNull_twice() {Joiner j = Joiner.on("x").useForNull("y");try {j = j.useForNull("y");fail();} catch (UnsupportedOperationException expected) {}}public void testMap() {MapJoiner j = Joiner.on(';').withKeyValueSeparator(':');assertEquals("", j.join(ImmutableMap.of()));assertEquals(":", j.join(ImmutableMap.of("", "")));Map<String, String> mapWithNulls = Maps.newLinkedHashMap();mapWithNulls.put("a", null);mapWithNulls.put(null, "b");try {j.join(mapWithNulls);fail();} catch (NullPointerException expected) {}assertEquals("a:00;00:b", j.useForNull("00").join(mapWithNulls));StringBuilder sb = new StringBuilder();j.appendTo(sb, ImmutableMap.of(1, 2, 3, 4, 5, 6));assertEquals("1:2;3:4;5:6", sb.toString());}public void testEntries() {MapJoiner j = Joiner.on(";").withKeyValueSeparator(":");assertEquals("", j.join(ImmutableMultimap.of().entries()));assertEquals("", j.join(ImmutableMultimap.of().entries().iterator()));assertEquals(":", j.join(ImmutableMultimap.of("", "").entries()));assertEquals(":", j.join(ImmutableMultimap.of("", "").entries().iterator()));assertEquals("1:a;1:b", j.join(ImmutableMultimap.of("1", "a", "1", "b").entries()));assertEquals("1:a;1:b", j.join(ImmutableMultimap.of("1", "a", "1", "b").entries().iterator()));Map<String, String> mapWithNulls = Maps.newLinkedHashMap();mapWithNulls.put("a", null);mapWithNulls.put(null, "b");Set<Entry<String, String>> entriesWithNulls = mapWithNulls.entrySet();try {j.join(entriesWithNulls);fail();} catch (NullPointerException expected) {}try {j.join(entriesWithNulls.iterator());fail();} catch (NullPointerException expected) {}assertEquals("a:00;00:b", j.useForNull("00").join(entriesWithNulls));assertEquals("a:00;00:b", j.useForNull("00").join(entriesWithNulls.iterator()));StringBuilder sb1 = new StringBuilder();j.appendTo(sb1, ImmutableMultimap.of(1, 2, 3, 4, 5, 6, 1, 3, 5, 10).entries());assertEquals("1:2;1:3;3:4;5:6;5:10", sb1.toString());StringBuilder sb2 = new StringBuilder();j.appendTo(sb2, ImmutableMultimap.of(1, 2, 3, 4, 5, 6, 1, 3, 5, 10).entries().iterator());assertEquals("1:2;1:3;3:4;5:6;5:10", sb2.toString());}public void test_skipNulls_onMap() {Joiner j = Joiner.on(",").skipNulls();try {j.withKeyValueSeparator("/");fail();} catch (UnsupportedOperationException expected) {}}private static class DontStringMeBro implements CharSequence {@Overridepublic int length() {return 3;}@Overridepublic char charAt(int index) {return "foo".charAt(index);}@Overridepublic CharSequence subSequence(int start, int end) {return "foo".subSequence(start, end);}@Overridepublic String toString() {throw new AssertionFailedError("shouldn't be invoked");}}// Don't do this.private static class IterableIterator implements Iterable<Integer>, Iterator<Integer> {private static final ImmutableSet<Integer> INTEGERS = ImmutableSet.of(1, 2, 3, 4);private final Iterator<Integer> iterator;public IterableIterator() {this.iterator = iterator();}@Overridepublic Iterator<Integer> iterator() {return INTEGERS.iterator();}@Overridepublic boolean hasNext() {return iterator.hasNext();}@Overridepublic Integer next() {return iterator.next();}@Overridepublic void remove() {iterator.remove();}}@GwtIncompatible // StringBuilder.append in GWT invokes Object.toString(), unlike the JRE version.public void testDontConvertCharSequenceToString() {assertEquals("foo,foo", Joiner.on(",").join(new DontStringMeBro(), new DontStringMeBro()));assertEquals("foo,bar,foo",Joiner.on(",").useForNull("bar").join(new DontStringMeBro(), null, new DontStringMeBro()));}@GwtIncompatible // NullPointerTesterpublic void testNullPointers() {NullPointerTester tester = new NullPointerTester();tester.testAllPublicStaticMethods(Joiner.class);tester.testInstanceMethods(Joiner.on(","), NullPointerTester.Visibility.PACKAGE);tester.testInstanceMethods(Joiner.on(",").skipNulls(), NullPointerTester.Visibility.PACKAGE);tester.testInstanceMethods(Joiner.on(",").useForNull("x"), NullPointerTester.Visibility.PACKAGE);tester.testInstanceMethods(Joiner.on(",").withKeyValueSeparator("="), NullPointerTester.Visibility.PACKAGE);}
}

6.Splitter拆分器

用于拆分字符串的内置Java工具具有一些古怪的行为。例如,String.split会静默丢弃尾部的分隔符,而StringTokenizer只考虑五个空格字符而不考虑其它字符。

测验:",a,,b,".split(",")返回什么?

  1. "", "a", "", "b", ""
  2. null, "a", null, "b", null
  3. "a", null, "b"
  4. "a", "b"
  5. 不是上述任何一个

正确的答案不是上述任何一个"", "a", "", "b"。只跳过尾部的空字符串。

Splitter拆分器使用令人放心的直接流利的模式,可以完全控制所有这些令人困惑的行为。

Splitter.on(',').trimResults().omitEmptyStrings().split("foo,bar,,   qux");

返回包含"foo", “bar”, "qux"的Iterable<String>Splitter拆分器可以设置在任何PatterncharStringCharMatcher上拆分。

6.1基本工厂

方法 描述 示例
Splitter.on(char) 根据出现的特定单个字符进行拆分。 Splitter.on(';')
Splitter.on(CharMatcher) 根据出现的某个类别中任意字符进行拆分。 Splitter.on(CharMatcher.BREAKING_WHITESPACE) Splitter.on(CharMatcher.anyOf(";,."))
Splitter.on(String) String字符串上分割。 Splitter.on(", ")
Splitter.on(Pattern) Splitter.onPattern(String) 按正则表达式拆分。 Splitter.onPattern("\r?\n")
Splitter.fixedLength(int) 将字符串拆分为指定固定长度的子字符串。最后一项可以小于length长度,但永远不会为空。 Splitter.fixedLength(3)

6.2修饰符

方法 描述 示例
omitEmptyStrings() 自动从结果中删除空字符串。 Splitter.on(',').omitEmptyStrings().split("a,,c,d") returns "a", "c", "d"
trimResults() 从结果中修剪空格;等效于trimResults(CharMatcher.WHITESPACE). Splitter.on(',').trimResults().split("a, b, c, d") returns "a", "b", "c", "d"
trimResults(CharMatcher) 从结果中修剪与指定CharMatcher匹配的字符。 Splitter.on(',').trimResults(CharMatcher.is('_')).split("_a ,_b_ ,c__") returns "a ", "b_ ", "c".
limit(int) 返回指定数量的字符串后停止拆分。 Splitter.on(',').limit(3).split("a,b,c,d") returns "a", "b", "c,d"

如果希望获取List列表,请使用splitToList()代替split()

警告: 拆分器实例始终是不可变的。拆分器配置方法将始终返回新的Splitter拆分器,必须使用它来获取所需的语义。这样可以确保任何Splitter线程安全,并可用作static final静态最终常量。

6.3Map拆分器

还可以使用拆分器通过使用withKeyValueSeparator()指定第二个分隔符对map进行反序列化。生成的MapSplitter 将使用拆分器的分隔符将输入拆分为条目,然后使用给定的键值分隔符将这些条目拆分为键和值,并返回Map<String, String>

6.4使用示例

import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import com.google.common.base.Splitter.MapSplitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.testing.NullPointerTester;
import junit.framework.TestCase;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;public class SplitterTest extends TestCase {private static final Splitter COMMA_SPLITTER = Splitter.on(',');public void testSplitNullString() {try {COMMA_SPLITTER.split(null);fail();} catch (NullPointerException expected) {}}public void testCharacterSimpleSplit() {String simple = "a,b,c";Iterable<String> letters = COMMA_SPLITTER.split(simple);assertThat(letters).containsExactly("a", "b", "c").inOrder();}public void testCharacterSimpleSplitToList() {String simple = "a,b,c";List<String> letters = COMMA_SPLITTER.splitToList(simple);assertThat(letters).containsExactly("a", "b", "c").inOrder();}public void testCharacterSimpleSplitToStream() {String simple = "a,b,c";List<String> letters = COMMA_SPLITTER.splitToStream(simple).collect(toImmutableList());assertThat(letters).containsExactly("a", "b", "c").inOrder();}public void testToString() {assertEquals("[]", COMMA_SPLITTER.split("").toString());assertEquals("[a, b, c]", COMMA_SPLITTER.split("a,b,c").toString());assertEquals("[yam, bam, jam, ham]", Splitter.on(", ").split("yam, bam, jam, ham").toString());}public void testCharacterSimpleSplitWithNoDelimiter() {String simple = "a,b,c";Iterable<String> letters = Splitter.on('.').split(simple);assertThat(letters).containsExactly("a,b,c").inOrder();}public void testCharacterSplitWithDoubleDelimiter() {String doubled = "a,,b,c";Iterable<String> letters = COMMA_SPLITTER.split(doubled);assertThat(letters).containsExactly("a", "", "b", "c").inOrder();}public void testCharacterSplitWithDoubleDelimiterAndSpace() {String doubled = "a,, b,c";Iterable<String> letters = COMMA_SPLITTER.split(doubled);assertThat(letters).containsExactly("a", "", " b", "c").inOrder();}public void testCharacterSplitWithTrailingDelimiter() {String trailing = "a,b,c,";Iterable<String> letters = COMMA_SPLITTER.split(trailing);assertThat(letters).containsExactly("a", "b", "c", "").inOrder();}public void testCharacterSplitWithLeadingDelimiter() {String leading = ",a,b,c";Iterable<String> letters = COMMA_SPLITTER.split(leading);assertThat(letters).containsExactly("", "a", "b", "c").inOrder();}public void testCharacterSplitWithMultipleLetters() {Iterable<String> testCharacteringMotto =Splitter.on('-').split("Testing-rocks-Debugging-sucks");assertThat(testCharacteringMotto).containsExactly("Testing", "rocks", "Debugging", "sucks").inOrder();}public void testCharacterSplitWithMatcherDelimiter() {Iterable<String> testCharacteringMotto =Splitter.on(CharMatcher.whitespace()).split("Testing\nrocks\tDebugging sucks");assertThat(testCharacteringMotto).containsExactly("Testing", "rocks", "Debugging", "sucks").inOrder();}public void testCharacterSplitWithDoubleDelimiterOmitEmptyStrings() {String doubled = "a..b.c";Iterable<String> letters = Splitter.on('.').omitEmptyStrings().split(doubled);assertThat(letters).containsExactly("a", "b", "c").inOrder();}public void testCharacterSplitEmptyToken() {String emptyToken = "a. .c";Iterable<String> letters = Splitter.on('.').trimResults().split(emptyToken);assertThat(letters).containsExactly("a", "", "c").inOrder();}public void testCharacterSplitEmptyTokenOmitEmptyStrings() {String emptyToken = "a. .c";Iterable<String> letters = Splitter.on('.').omitEmptyStrings().trimResults().split(emptyToken);assertThat(letters).containsExactly("a", "c").inOrder();}public void testCharacterSplitOnEmptyString() {Iterable<String> nothing = Splitter.on('.').split("");assertThat(nothing).containsExactly("").inOrder();}public void testCharacterSplitOnEmptyStringOmitEmptyStrings() {assertThat(Splitter.on('.').omitEmptyStrings().split("")).isEmpty();}public void testCharacterSplitOnOnlyDelimiter() {Iterable<String> blankblank = Splitter.on('.').split(".");assertThat(blankblank).containsExactly("", "").inOrder();}public void testCharacterSplitOnOnlyDelimitersOmitEmptyStrings() {Iterable<String> empty = Splitter.on('.').omitEmptyStrings().split("...");assertThat(empty).isEmpty();}public void testCharacterSplitWithTrim() {String jacksons ="arfo(Marlon)aorf, (Michael)orfa, afro(Jackie)orfa, " + "ofar(Jemaine), aff(Tito)";Iterable<String> family =COMMA_SPLITTER.trimResults(CharMatcher.anyOf("afro").or(CharMatcher.whitespace())).split(jacksons);assertThat(family).containsExactly("(Marlon)", "(Michael)", "(Jackie)", "(Jemaine)", "(Tito)").inOrder();}public void testStringSimpleSplit() {String simple = "a,b,c";Iterable<String> letters = Splitter.on(",").split(simple);assertThat(letters).containsExactly("a", "b", "c").inOrder();}public void testStringSimpleSplitWithNoDelimiter() {String simple = "a,b,c";Iterable<String> letters = Splitter.on(".").split(simple);assertThat(letters).containsExactly("a,b,c").inOrder();}public void testStringSplitWithDoubleDelimiter() {String doubled = "a,,b,c";Iterable<String> letters = Splitter.on(",").split(doubled);assertThat(letters).containsExactly("a", "", "b", "c").inOrder();}public void testStringSplitWithDoubleDelimiterAndSpace() {String doubled = "a,, b,c";Iterable<String> letters = Splitter.on(",").split(doubled);assertThat(letters).containsExactly("a", "", " b", "c").inOrder();}public void testStringSplitWithTrailingDelimiter() {String trailing = "a,b,c,";Iterable<String> letters = Splitter.on(",").split(trailing);assertThat(letters).containsExactly("a", "b", "c", "").inOrder();}public void testStringSplitWithLeadingDelimiter() {String leading = ",a,b,c";Iterable<String> letters = Splitter.on(",").split(leading);assertThat(letters).containsExactly("", "a", "b", "c").inOrder();}public void testStringSplitWithMultipleLetters() {Iterable<String> testStringingMotto = Splitter.on("-").split("Testing-rocks-Debugging-sucks");assertThat(testStringingMotto).containsExactly("Testing", "rocks", "Debugging", "sucks").inOrder();}public void testStringSplitWithDoubleDelimiterOmitEmptyStrings() {String doubled = "a..b.c";Iterable<String> letters = Splitter.on(".").omitEmptyStrings().split(doubled);assertThat(letters).containsExactly("a", "b", "c").inOrder();}public void testStringSplitEmptyToken() {String emptyToken = "a. .c";Iterable<String> letters = Splitter.on(".").trimResults().split(emptyToken);assertThat(letters).containsExactly("a", "", "c").inOrder();}public void testStringSplitEmptyTokenOmitEmptyStrings() {String emptyToken = "a. .c";Iterable<String> letters = Splitter.on(".").omitEmptyStrings().trimResults().split(emptyToken);assertThat(letters).containsExactly("a", "c").inOrder();}public void testStringSplitWithLongDelimiter() {String longDelimiter = "a, b, c";Iterable<String> letters = Splitter.on(", ").split(longDelimiter);assertThat(letters).containsExactly("a", "b", "c").inOrder();}public void testStringSplitWithLongLeadingDelimiter() {String longDelimiter = ", a, b, c";Iterable<String> letters = Splitter.on(", ").split(longDelimiter);assertThat(letters).containsExactly("", "a", "b", "c").inOrder();}public void testStringSplitWithLongTrailingDelimiter() {String longDelimiter = "a, b, c, ";Iterable<String> letters = Splitter.on(", ").split(longDelimiter);assertThat(letters).containsExactly("a", "b", "c", "").inOrder();}public void testStringSplitWithDelimiterSubstringInValue() {String fourCommasAndFourSpaces = ",,,,    ";Iterable<String> threeCommasThenThreeSpaces = Splitter.on(", ").split(fourCommasAndFourSpaces);assertThat(threeCommasThenThreeSpaces).containsExactly(",,,", "   ").inOrder();}public void testStringSplitWithEmptyString() {try {Splitter.on("");fail();} catch (IllegalArgumentException expected) {}}public void testStringSplitOnEmptyString() {Iterable<String> notMuch = Splitter.on(".").split("");assertThat(notMuch).containsExactly("").inOrder();}public void testStringSplitOnEmptyStringOmitEmptyString() {assertThat(Splitter.on(".").omitEmptyStrings().split("")).isEmpty();}public void testStringSplitOnOnlyDelimiter() {Iterable<String> blankblank = Splitter.on(".").split(".");assertThat(blankblank).containsExactly("", "").inOrder();}public void testStringSplitOnOnlyDelimitersOmitEmptyStrings() {Iterable<String> empty = Splitter.on(".").omitEmptyStrings().split("...");assertThat(empty).isEmpty();}public void testStringSplitWithTrim() {String jacksons ="arfo(Marlon)aorf, (Michael)orfa, afro(Jackie)orfa, " + "ofar(Jemaine), aff(Tito)";Iterable<String> family =Splitter.on(",").trimResults(CharMatcher.anyOf("afro").or(CharMatcher.whitespace())).split(jacksons);assertThat(family).containsExactly("(Marlon)", "(Michael)", "(Jackie)", "(Jemaine)", "(Tito)").inOrder();}@GwtIncompatible // Splitter.onPatternpublic void testPatternSimpleSplit() {String simple = "a,b,c";Iterable<String> letters = Splitter.onPattern(",").split(simple);assertThat(letters).containsExactly("a", "b", "c").inOrder();}@GwtIncompatible // Splitter.onPatternpublic void testPatternSimpleSplitWithNoDelimiter() {String simple = "a,b,c";Iterable<String> letters = Splitter.onPattern("foo").split(simple);assertThat(letters).containsExactly("a,b,c").inOrder();}@GwtIncompatible // Splitter.onPatternpublic void testPatternSplitWithDoubleDelimiter() {String doubled = "a,,b,c";Iterable<String> letters = Splitter.onPattern(",").split(doubled);assertThat(letters).containsExactly("a", "", "b", "c").inOrder();}@GwtIncompatible // Splitter.onPatternpublic void testPatternSplitWithDoubleDelimiterAndSpace() {String doubled = "a,, b,c";Iterable<String> letters = Splitter.onPattern(",").split(doubled);assertThat(letters).containsExactly("a", "", " b", "c").inOrder();}@GwtIncompatible // Splitter.onPatternpublic void testPatternSplitWithTrailingDelimiter() {String trailing = "a,b,c,";Iterable<String> letters = Splitter.onPattern(",").split(trailing);assertThat(letters).containsExactly("a", "b", "c", "").inOrder();}@GwtIncompatible // Splitter.onPatternpublic void testPatternSplitWithLeadingDelimiter() {String leading = ",a,b,c";Iterable<String> letters = Splitter.onPattern(",").split(leading);assertThat(letters).containsExactly("", "a", "b", "c").inOrder();}@GwtIncompatible // Splitter.onPatternpublic void testPatternSplitWithMultipleLetters() {Iterable<String> testPatterningMotto =Splitter.onPattern("-").split("Testing-rocks-Debugging-sucks");assertThat(testPatterningMotto).containsExactly("Testing", "rocks", "Debugging", "sucks").inOrder();}@GwtIncompatible // java.util.regex.Patternprivate static Pattern literalDotPattern() {return Pattern.compile("\\.");}@GwtIncompatible // java.util.regex.Patternpublic void testPatternSplitWithDoubleDelimiterOmitEmptyStrings() {String doubled = "a..b.c";Iterable<String> letters = Splitter.on(literalDotPattern()).omitEmptyStrings().split(doubled);assertThat(letters).containsExactly("a", "b", "c").inOrder();}@GwtIncompatible // java.util.regex.Patternpublic void testPatternSplitWordBoundary() {String string = "foo<bar>bletch";Iterable<String> words = Splitter.on(Pattern.compile("\\b")).split(string);assertThat(words).containsExactly("foo", "<", "bar", ">", "bletch").inOrder();}@GwtIncompatible // java.util.regex.Patternpublic void testPatternSplitWordBoundary_singleCharInput() {String string = "f";Iterable<String> words = Splitter.on(Pattern.compile("\\b")).split(string);assertThat(words).containsExactly("f").inOrder();}@GwtIncompatible // java.util.regex.Patternpublic void testPatternSplitWordBoundary_singleWordInput() {String string = "foo";Iterable<String> words = Splitter.on(Pattern.compile("\\b")).split(string);assertThat(words).containsExactly("foo").inOrder();}@GwtIncompatible // java.util.regex.Patternpublic void testPatternSplitEmptyToken() {String emptyToken = "a. .c";Iterable<String> letters = Splitter.on(literalDotPattern()).trimResults().split(emptyToken);assertThat(letters).containsExactly("a", "", "c").inOrder();}@GwtIncompatible // java.util.regex.Patternpublic void testPatternSplitEmptyTokenOmitEmptyStrings() {String emptyToken = "a. .c";Iterable<String> letters =Splitter.on(literalDotPattern()).omitEmptyStrings().trimResults().split(emptyToken);assertThat(letters).containsExactly("a", "c").inOrder();}@GwtIncompatible // java.util.regex.Patternpublic void testPatternSplitOnOnlyDelimiter() {Iterable<String> blankblank = Splitter.on(literalDotPattern()).split(".");assertThat(blankblank).containsExactly("", "").inOrder();}@GwtIncompatible // java.util.regex.Patternpublic void testPatternSplitOnOnlyDelimitersOmitEmptyStrings() {Iterable<String> empty = Splitter.on(literalDotPattern()).omitEmptyStrings().split("...");assertThat(empty).isEmpty();}@GwtIncompatible // java.util.regex.Patternpublic void testPatternSplitMatchingIsGreedy() {String longDelimiter = "a, b,   c";Iterable<String> letters = Splitter.on(Pattern.compile(",\\s*")).split(longDelimiter);assertThat(letters).containsExactly("a", "b", "c").inOrder();}@GwtIncompatible // java.util.regex.Patternpublic void testPatternSplitWithLongLeadingDelimiter() {String longDelimiter = ", a, b, c";Iterable<String> letters = Splitter.on(Pattern.compile(", ")).split(longDelimiter);assertThat(letters).containsExactly("", "a", "b", "c").inOrder();}@GwtIncompatible // java.util.regex.Patternpublic void testPatternSplitWithLongTrailingDelimiter() {String longDelimiter = "a, b, c/ ";Iterable<String> letters = Splitter.on(Pattern.compile("[,/]\\s")).split(longDelimiter);assertThat(letters).containsExactly("a", "b", "c", "").inOrder();}@GwtIncompatible // java.util.regex.Patternpublic void testPatternSplitInvalidPattern() {try {Splitter.on(Pattern.compile("a*"));fail();} catch (IllegalArgumentException expected) {}}@GwtIncompatible // java.util.regex.Patternpublic void testPatternSplitWithTrim() {String jacksons ="arfo(Marlon)aorf, (Michael)orfa, afro(Jackie)orfa, " + "ofar(Jemaine), aff(Tito)";Iterable<String> family =Splitter.on(Pattern.compile(",")).trimResults(CharMatcher.anyOf("afro").or(CharMatcher.whitespace())).split(jacksons);assertThat(family).containsExactly("(Marlon)", "(Michael)", "(Jackie)", "(Jemaine)", "(Tito)").inOrder();}public void testSplitterIterableIsUnmodifiable_char() {assertIteratorIsUnmodifiable(COMMA_SPLITTER.split("a,b").iterator());}public void testSplitterIterableIsUnmodifiable_string() {assertIteratorIsUnmodifiable(Splitter.on(",").split("a,b").iterator());}@GwtIncompatible // java.util.regex.Patternpublic void testSplitterIterableIsUnmodifiable_pattern() {assertIteratorIsUnmodifiable(Splitter.on(Pattern.compile(",")).split("a,b").iterator());}private void assertIteratorIsUnmodifiable(Iterator<?> iterator) {iterator.next();try {iterator.remove();fail();} catch (UnsupportedOperationException expected) {}}public void testSplitterIterableIsLazy_char() {assertSplitterIterableIsLazy(COMMA_SPLITTER);}public void testSplitterIterableIsLazy_string() {assertSplitterIterableIsLazy(Splitter.on(","));}/*** This test really pushes the boundaries of what we support. In general the splitter's behaviour* is not well defined if the char sequence it's splitting is mutated during iteration.*/private void assertSplitterIterableIsLazy(Splitter splitter) {StringBuilder builder = new StringBuilder();Iterator<String> iterator = splitter.split(builder).iterator();builder.append("A,");assertEquals("A", iterator.next());builder.append("B,");assertEquals("B", iterator.next());builder.append("C");assertEquals("C", iterator.next());assertFalse(iterator.hasNext());}public void testFixedLengthSimpleSplit() {String simple = "abcde";Iterable<String> letters = Splitter.fixedLength(2).split(simple);assertThat(letters).containsExactly("ab", "cd", "e").inOrder();}public void testFixedLengthSplitEqualChunkLength() {String simple = "abcdef";Iterable<String> letters = Splitter.fixedLength(2).split(simple);assertThat(letters).containsExactly("ab", "cd", "ef").inOrder();}public void testFixedLengthSplitOnlyOneChunk() {String simple = "abc";Iterable<String> letters = Splitter.fixedLength(3).split(simple);assertThat(letters).containsExactly("abc").inOrder();}public void testFixedLengthSplitSmallerString() {String simple = "ab";Iterable<String> letters = Splitter.fixedLength(3).split(simple);assertThat(letters).containsExactly("ab").inOrder();}public void testFixedLengthSplitEmptyString() {String simple = "";Iterable<String> letters = Splitter.fixedLength(3).split(simple);assertThat(letters).containsExactly("").inOrder();}public void testFixedLengthSplitEmptyStringWithOmitEmptyStrings() {assertThat(Splitter.fixedLength(3).omitEmptyStrings().split("")).isEmpty();}public void testFixedLengthSplitIntoChars() {String simple = "abcd";Iterable<String> letters = Splitter.fixedLength(1).split(simple);assertThat(letters).containsExactly("a", "b", "c", "d").inOrder();}public void testFixedLengthSplitZeroChunkLen() {try {Splitter.fixedLength(0);fail();} catch (IllegalArgumentException expected) {}}public void testFixedLengthSplitNegativeChunkLen() {try {Splitter.fixedLength(-1);fail();} catch (IllegalArgumentException expected) {}}public void testLimitLarge() {String simple = "abcd";Iterable<String> letters = Splitter.fixedLength(1).limit(100).split(simple);assertThat(letters).containsExactly("a", "b", "c", "d").inOrder();}public void testLimitOne() {String simple = "abcd";Iterable<String> letters = Splitter.fixedLength(1).limit(1).split(simple);assertThat(letters).containsExactly("abcd").inOrder();}public void testLimitFixedLength() {String simple = "abcd";Iterable<String> letters = Splitter.fixedLength(1).limit(2).split(simple);assertThat(letters).containsExactly("a", "bcd").inOrder();}public void testLimit1Separator() {String simple = "a,b,c,d";Iterable<String> items = COMMA_SPLITTER.limit(1).split(simple);assertThat(items).containsExactly("a,b,c,d").inOrder();}public void testLimitSeparator() {String simple = "a,b,c,d";Iterable<String> items = COMMA_SPLITTER.limit(2).split(simple);assertThat(items).containsExactly("a", "b,c,d").inOrder();}public void testLimitExtraSeparators() {String text = "a,,,b,,c,d";Iterable<String> items = COMMA_SPLITTER.limit(2).split(text);assertThat(items).containsExactly("a", ",,b,,c,d").inOrder();}public void testLimitExtraSeparatorsOmitEmpty() {String text = "a,,,b,,c,d";Iterable<String> items = COMMA_SPLITTER.limit(2).omitEmptyStrings().split(text);assertThat(items).containsExactly("a", "b,,c,d").inOrder();}public void testLimitExtraSeparatorsOmitEmpty3() {String text = "a,,,b,,c,d";Iterable<String> items = COMMA_SPLITTER.limit(3).omitEmptyStrings().split(text);assertThat(items).containsExactly("a", "b", "c,d").inOrder();}public void testLimitExtraSeparatorsTrim() {String text = ",,a,,  , b ,, c,d ";Iterable<String> items = COMMA_SPLITTER.limit(2).omitEmptyStrings().trimResults().split(text);assertThat(items).containsExactly("a", "b ,, c,d").inOrder();}public void testLimitExtraSeparatorsTrim3() {String text = ",,a,,  , b ,, c,d ";Iterable<String> items = COMMA_SPLITTER.limit(3).omitEmptyStrings().trimResults().split(text);assertThat(items).containsExactly("a", "b", "c,d").inOrder();}public void testLimitExtraSeparatorsTrim1() {String text = ",,a,,  , b ,, c,d ";Iterable<String> items = COMMA_SPLITTER.limit(1).omitEmptyStrings().trimResults().split(text);assertThat(items).containsExactly("a,,  , b ,, c,d").inOrder();}public void testLimitExtraSeparatorsTrim1NoOmit() {String text = ",,a,,  , b ,, c,d ";Iterable<String> items = COMMA_SPLITTER.limit(1).trimResults().split(text);assertThat(items).containsExactly(",,a,,  , b ,, c,d").inOrder();}public void testLimitExtraSeparatorsTrim1Empty() {String text = "";Iterable<String> items = COMMA_SPLITTER.limit(1).split(text);assertThat(items).containsExactly("").inOrder();}public void testLimitExtraSeparatorsTrim1EmptyOmit() {String text = "";Iterable<String> items = COMMA_SPLITTER.omitEmptyStrings().limit(1).split(text);assertThat(items).isEmpty();}public void testInvalidZeroLimit() {try {COMMA_SPLITTER.limit(0);fail();} catch (IllegalArgumentException expected) {}}@GwtIncompatible // NullPointerTesterpublic void testNullPointers() {NullPointerTester tester = new NullPointerTester();tester.testAllPublicStaticMethods(Splitter.class);tester.testAllPublicInstanceMethods(COMMA_SPLITTER);tester.testAllPublicInstanceMethods(COMMA_SPLITTER.trimResults());}public void testMapSplitter_trimmedBoth() {Map<String, String> m =COMMA_SPLITTER.trimResults().withKeyValueSeparator(Splitter.on(':').trimResults()).split("boy  : tom , girl: tina , cat  : kitty , dog: tommy ");ImmutableMap<String, String> expected =ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy");assertThat(m).isEqualTo(expected);assertThat(m.entrySet()).containsExactlyElementsIn(expected.entrySet()).inOrder();}public void testMapSplitter_trimmedEntries() {Map<String, String> m =COMMA_SPLITTER.trimResults().withKeyValueSeparator(":").split("boy  : tom , girl: tina , cat  : kitty , dog: tommy ");ImmutableMap<String, String> expected =ImmutableMap.of("boy  ", " tom", "girl", " tina", "cat  ", " kitty", "dog", " tommy");assertThat(m).isEqualTo(expected);assertThat(m.entrySet()).containsExactlyElementsIn(expected.entrySet()).inOrder();}public void testMapSplitter_trimmedKeyValue() {Map<String, String> m =COMMA_SPLITTER.withKeyValueSeparator(Splitter.on(':').trimResults()).split("boy  : tom , girl: tina , cat  : kitty , dog: tommy ");ImmutableMap<String, String> expected =ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy");assertThat(m).isEqualTo(expected);assertThat(m.entrySet()).containsExactlyElementsIn(expected.entrySet()).inOrder();}public void testMapSplitter_notTrimmed() {Map<String, String> m =COMMA_SPLITTER.withKeyValueSeparator(":").split(" boy:tom , girl: tina , cat :kitty , dog:  tommy ");ImmutableMap<String, String> expected =ImmutableMap.of(" boy", "tom ", " girl", " tina ", " cat ", "kitty ", " dog", "  tommy ");assertThat(m).isEqualTo(expected);assertThat(m.entrySet()).containsExactlyElementsIn(expected.entrySet()).inOrder();}public void testMapSplitter_CharacterSeparator() {// try different delimiters.Map<String, String> m =Splitter.on(",").withKeyValueSeparator(':').split("boy:tom,girl:tina,cat:kitty,dog:tommy");ImmutableMap<String, String> expected =ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy");assertThat(m).isEqualTo(expected);assertThat(m.entrySet()).containsExactlyElementsIn(expected.entrySet()).inOrder();}public void testMapSplitter_multiCharacterSeparator() {// try different delimiters.Map<String, String> m =Splitter.on(",").withKeyValueSeparator(":^&").split("boy:^&tom,girl:^&tina,cat:^&kitty,dog:^&tommy");ImmutableMap<String, String> expected =ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy");assertThat(m).isEqualTo(expected);assertThat(m.entrySet()).containsExactlyElementsIn(expected.entrySet()).inOrder();}public void testMapSplitter_emptySeparator() {try {COMMA_SPLITTER.withKeyValueSeparator("");fail();} catch (IllegalArgumentException expected) {}}public void testMapSplitter_malformedEntry() {try {COMMA_SPLITTER.withKeyValueSeparator("=").split("a=1,b,c=2");fail();} catch (IllegalArgumentException expected) {}}/*** Testing the behavior in https://github.com/google/guava/issues/1900 - this behavior may want to* be changed?*/public void testMapSplitter_extraValueDelimiter() {try {COMMA_SPLITTER.withKeyValueSeparator("=").split("a=1,c=2=");fail();} catch (IllegalArgumentException expected) {}}public void testMapSplitter_orderedResults() {Map<String, String> m =COMMA_SPLITTER.withKeyValueSeparator(":").split("boy:tom,girl:tina,cat:kitty,dog:tommy");assertThat(m.keySet()).containsExactly("boy", "girl", "cat", "dog").inOrder();assertThat(m).isEqualTo(ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy"));// try in a different orderm = COMMA_SPLITTER.withKeyValueSeparator(":").split("girl:tina,boy:tom,dog:tommy,cat:kitty");assertThat(m.keySet()).containsExactly("girl", "boy", "dog", "cat").inOrder();assertThat(m).isEqualTo(ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy"));}public void testMapSplitter_duplicateKeys() {try {COMMA_SPLITTER.withKeyValueSeparator(":").split("a:1,b:2,a:3");fail();} catch (IllegalArgumentException expected) {}}public void testMapSplitter_varyingTrimLevels() {MapSplitter splitter = COMMA_SPLITTER.trimResults().withKeyValueSeparator(Splitter.on("->"));Map<String, String> split = splitter.split(" x -> y, z-> a ");assertThat(split).containsEntry("x ", " y");assertThat(split).containsEntry("z", " a");}
}

7.Strings字符串处理

Strings类中存在数量有限的通用String字符串工具。

StringCharSequence实例有关的静态工具方法。

7.1静态方法

方法 描述
String nullToEmpty(@Nullable String string) 如果给定的字符串为非null,则返回该字符串;否则为空字符串。
String emptyToNull(@Nullable String string) 如果给定的字符串非空,则返回该字符串;否则为null
boolean isNullOrEmpty(@Nullable String string) 如果给定的字符串为null或为空字符串,则返回true。考虑使用nullToEmpty规范化字符串引用。
如果这样做,则可以使用String.isEmpty()代替此方法,并且也不需要特殊的null安全形式的方法,例如String.toUpperCase。或者,如果想"以另一种方式"进行标准化,则将空字符串转换为null,则可以使用emptyToNull
String padStart(String string, int minLength, char padChar) 返回一个长度至少为minLength的字符串,该字符串由string组成,前缀为达到该长度所需的padChar副本。例如,
padStart("7", 3, '0') returns "007"; padStart("2010", 3, '0') returns "2010"
请参阅java.util.Formatter,以获取更多的格式化功能。
String padEnd(String string, int minLength, char padChar) 返回长度至少为minLength的字符串,该字符串由string组成,附加了达到该长度所需的padChar副本。例如,
padEnd("4.", 5, '0') returns "4.000"; padEnd("2010", 3, '!') returns "2010"
请参阅java.util.Formatter,以获取更多的格式化功能。
String repeat(String string, int count) 返回由输入字符串的特定数量的级联副本组成的字符串。例如,repeat("hey", 3)返回字符串"heyheyhey"。返回一个包含string的字符串,该字符串重复了count次(如果count为零,则返回空字符串)。如果count是负数则抛出IllegalArgumentException
String commonPrefix(CharSequence a, CharSequence b) 返回最长的字符串前缀,以使a.toString().startsWith(prefix) && b.toString().startsWith(prefix),注意不要拆分代理对。如果ab没有共同的前缀,则返回空字符串。
String commonSuffix(CharSequence a, CharSequence b) 返回最长的字符串后缀,以使a.toString().endsWith(suffix) && b.toString().endsWith(suffix),注意不要拆分代理对。如果ab没有共同的后缀,则返回空字符串。
String lenientFormat(<br/> @Nullable String template, @Nullable Object @Nullable ... args) 返回给定的template字符串,其中每次出现的"%s"args中的相应参数值替换;或者,如果占位符和参数计数不匹配,则返回该字符串的尽力而为形式。在正常情况下不会抛出异常。
注意: 对于大多数字符串格式需求,请使用String.formatjava.io.PrintWriter.format和相关方法。这些支持全部格式说明符,并提醒你通过抛出java.util.IllegalFormatException来解决使用错误。
在某些情况下,例如输出调试信息或构造用于另一个未经检查的异常的消息,字符串格式化期间的异常除了取代你试图提供的真实信息外,几乎没有什么用处。这些就是这种方法适用的情况;相反,它会生成带有所有提供的参数值的尽力而为字符串。此方法在String.format不可用的GWT等环境中也很有用。例如,出于上述两个原因,Preconditions类的方法实现使用此格式化程序。
警告: 仅识别精确的两个字符的占位符序列"%s"

7.2使用示例

import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Strings;
import com.google.common.testing.NullPointerTester;
import junit.framework.TestCase;import static com.google.common.truth.Truth.assertThat;public class StringsTest extends TestCase {public void testNullToEmpty() {assertEquals("", Strings.nullToEmpty(null));assertEquals("", Strings.nullToEmpty(""));assertEquals("a", Strings.nullToEmpty("a"));}public void testEmptyToNull() {assertNull(Strings.emptyToNull(null));assertNull(Strings.emptyToNull(""));assertEquals("a", Strings.emptyToNull("a"));}public void testIsNullOrEmpty() {assertTrue(Strings.isNullOrEmpty(null));assertTrue(Strings.isNullOrEmpty(""));assertFalse(Strings.isNullOrEmpty("a"));}public void testPadStart_noPadding() {assertSame("", Strings.padStart("", 0, '-'));assertSame("x", Strings.padStart("x", 0, '-'));assertSame("x", Strings.padStart("x", 1, '-'));assertSame("xx", Strings.padStart("xx", 0, '-'));assertSame("xx", Strings.padStart("xx", 2, '-'));}public void testPadStart_somePadding() {assertEquals("-", Strings.padStart("", 1, '-'));assertEquals("--", Strings.padStart("", 2, '-'));assertEquals("-x", Strings.padStart("x", 2, '-'));assertEquals("--x", Strings.padStart("x", 3, '-'));assertEquals("-xx", Strings.padStart("xx", 3, '-'));}public void testPadStart_negativeMinLength() {assertSame("x", Strings.padStart("x", -1, '-'));}public void testPadStart_null() {try {Strings.padStart(null, 5, '0');fail();} catch (NullPointerException expected) {}}public void testPadEnd_noPadding() {assertSame("", Strings.padEnd("", 0, '-'));assertSame("x", Strings.padEnd("x", 0, '-'));assertSame("x", Strings.padEnd("x", 1, '-'));assertSame("xx", Strings.padEnd("xx", 0, '-'));assertSame("xx", Strings.padEnd("xx", 2, '-'));}public void testPadEnd_somePadding() {assertEquals("-", Strings.padEnd("", 1, '-'));assertEquals("--", Strings.padEnd("", 2, '-'));assertEquals("x-", Strings.padEnd("x", 2, '-'));assertEquals("x--", Strings.padEnd("x", 3, '-'));assertEquals("xx-", Strings.padEnd("xx", 3, '-'));}public void testPadEnd_negativeMinLength() {assertSame("x", Strings.padEnd("x", -1, '-'));}public void testPadEnd_null() {try {Strings.padEnd(null, 5, '0');fail();} catch (NullPointerException expected) {}}public void testRepeat() {String input = "20";assertEquals("", Strings.repeat(input, 0));assertEquals("20", Strings.repeat(input, 1));assertEquals("2020", Strings.repeat(input, 2));assertEquals("202020", Strings.repeat(input, 3));assertEquals("", Strings.repeat("", 4));for (int i = 0; i < 100; ++i) {assertEquals(2 * i, Strings.repeat(input, i).length());}try {Strings.repeat("x", -1);fail();} catch (IllegalArgumentException expected) {}try {// Massive stringStrings.repeat("12345678", (1 << 30) + 3);fail();} catch (ArrayIndexOutOfBoundsException expected) {}}public void testRepeat_null() {try {Strings.repeat(null, 5);fail();} catch (NullPointerException expected) {}}public void testCommonPrefix() {assertEquals("", Strings.commonPrefix("", ""));assertEquals("", Strings.commonPrefix("abc", ""));assertEquals("", Strings.commonPrefix("", "abc"));assertEquals("", Strings.commonPrefix("abcde", "xyz"));assertEquals("", Strings.commonPrefix("xyz", "abcde"));assertEquals("", Strings.commonPrefix("xyz", "abcxyz"));assertEquals("a", Strings.commonPrefix("abc", "aaaaa"));assertEquals("aa", Strings.commonPrefix("aa", "aaaaa"));assertEquals("abc", Strings.commonPrefix(new StringBuffer("abcdef"), "abcxyz"));// Identical valid surrogate pairs.assertEquals("abc\uD8AB\uDCAB", Strings.commonPrefix("abc\uD8AB\uDCABdef", "abc\uD8AB\uDCABxyz"));// Differing valid surrogate pairs.assertEquals("abc", Strings.commonPrefix("abc\uD8AB\uDCABdef", "abc\uD8AB\uDCACxyz"));// One invalid pair.assertEquals("abc", Strings.commonPrefix("abc\uD8AB\uDCABdef", "abc\uD8AB\uD8ABxyz"));// Two identical invalid pairs.assertEquals("abc\uD8AB\uD8AC", Strings.commonPrefix("abc\uD8AB\uD8ACdef", "abc\uD8AB\uD8ACxyz"));// Two differing invalid pairs.assertEquals("abc\uD8AB", Strings.commonPrefix("abc\uD8AB\uD8ABdef", "abc\uD8AB\uD8ACxyz"));// One orphan high surrogate.assertEquals("", Strings.commonPrefix("\uD8AB\uDCAB", "\uD8AB"));// Two orphan high surrogates.assertEquals("\uD8AB", Strings.commonPrefix("\uD8AB", "\uD8AB"));}public void testCommonSuffix() {assertEquals("", Strings.commonSuffix("", ""));assertEquals("", Strings.commonSuffix("abc", ""));assertEquals("", Strings.commonSuffix("", "abc"));assertEquals("", Strings.commonSuffix("abcde", "xyz"));assertEquals("", Strings.commonSuffix("xyz", "abcde"));assertEquals("", Strings.commonSuffix("xyz", "xyzabc"));assertEquals("c", Strings.commonSuffix("abc", "ccccc"));assertEquals("aa", Strings.commonSuffix("aa", "aaaaa"));assertEquals("abc", Strings.commonSuffix(new StringBuffer("xyzabc"), "xxxabc"));// Identical valid surrogate pairs.assertEquals("\uD8AB\uDCABdef", Strings.commonSuffix("abc\uD8AB\uDCABdef", "xyz\uD8AB\uDCABdef"));// Differing valid surrogate pairs.assertEquals("def", Strings.commonSuffix("abc\uD8AB\uDCABdef", "abc\uD8AC\uDCABdef"));// One invalid pair.assertEquals("def", Strings.commonSuffix("abc\uD8AB\uDCABdef", "xyz\uDCAB\uDCABdef"));// Two identical invalid pairs.assertEquals("\uD8AB\uD8ABdef", Strings.commonSuffix("abc\uD8AB\uD8ABdef", "xyz\uD8AB\uD8ABdef"));// Two differing invalid pairs.assertEquals("\uDCABdef", Strings.commonSuffix("abc\uDCAB\uDCABdef", "abc\uDCAC\uDCABdef"));// One orphan low surrogate.assertEquals("", Strings.commonSuffix("x\uD8AB\uDCAB", "\uDCAB"));// Two orphan low surrogates.assertEquals("\uDCAB", Strings.commonSuffix("\uDCAB", "\uDCAB"));}public void testLenientFormat() {assertEquals("%s", Strings.lenientFormat("%s"));assertEquals("5", Strings.lenientFormat("%s", 5));assertEquals("foo [5]", Strings.lenientFormat("foo", 5));assertEquals("foo [5, 6, 7]", Strings.lenientFormat("foo", 5, 6, 7));assertEquals("%s 1 2", Strings.lenientFormat("%s %s %s", "%s", 1, 2));assertEquals(" [5, 6]", Strings.lenientFormat("", 5, 6));assertEquals("123", Strings.lenientFormat("%s%s%s", 1, 2, 3));assertEquals("1%s%s", Strings.lenientFormat("%s%s%s", 1));assertEquals("5 + 6 = 11", Strings.lenientFormat("%s + 6 = 11", 5));assertEquals("5 + 6 = 11", Strings.lenientFormat("5 + %s = 11", 6));assertEquals("5 + 6 = 11", Strings.lenientFormat("5 + 6 = %s", 11));assertEquals("5 + 6 = 11", Strings.lenientFormat("%s + %s = %s", 5, 6, 11));assertEquals("null [null, null]", Strings.lenientFormat("%s", null, null, null));assertEquals("null [5, 6]", Strings.lenientFormat(null, 5, 6));assertEquals("null", Strings.lenientFormat("%s", (Object) null));assertEquals("(Object[])null", Strings.lenientFormat("%s", (Object[]) null));}@GwtIncompatible // GWT reflection includes less datapublic void testLenientFormat_badArgumentToString() {assertThat(Strings.lenientFormat("boiler %s plate", new ThrowsOnToString())).matches("boiler <com\\.google\\.common\\.base\\.StringsTest\\$ThrowsOnToString@[0-9a-f]+ "+ "threw java\\.lang\\.UnsupportedOperationException> plate");}public void testLenientFormat_badArgumentToString_gwtFriendly() {assertThat(Strings.lenientFormat("boiler %s plate", new ThrowsOnToString())).matches("boiler <.*> plate");}private static class ThrowsOnToString {@Overridepublic String toString() {throw new UnsupportedOperationException();}}@GwtIncompatible // NullPointerTesterpublic void testNullPointers() {NullPointerTester tester = new NullPointerTester();tester.testAllPublicStaticMethods(Strings.class);}
}

本文参考:
CharMatcher
Charsets
CaseFormat
Joiner
Splitter
Strings
guava-tests-base

Google Guava与字符串操作相关的类相关推荐

  1. [Google Guava] 2.4-集合扩展工具类

    原文链接 译文链接 译者:沈义扬,校对:丁一 简介 有时候你需要实现自己的集合扩展.也许你想要在元素被添加到列表时增加特定的行为,或者你想实现一个Iterable,其底层实际上是遍历数据库查询的结果集 ...

  2. com.google.guava包里面的相关简单方法

    pom坐标 <dependency><groupId>com.google.guava</groupId><artifactId>guava</a ...

  3. c语言中字符串操作的工具类

     1.编写头文件 #define _CRT_SECURE_NO_WARNINGS //#pragmawarning(disable:4996) #include <stdio.h> # ...

  4. Google Guava官方教程(中文版)gu

    Google Guava官方教程(中文版) 原文链接  译文链接 译者: 沈义扬,罗立树,何一昕,武祖  校对:方腾飞 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库, ...

  5. [19/04/04-星期四] IO技术_CommonsIO(通用IO,别人造的轮子,FileUtils类 操作文件 IOUtilsl类 操作里边的内容 )...

    一.概念 JDK中提供的文件操作相关的类,但是功能都非常基础,进行复杂操作时需要做大量编程工作.实际开发中,往往需要 你自己动手编写相关的代码,尤其在遍历目录文件时,经常用到递归,非常繁琐. Apac ...

  6. freecplus框架-字符串操作

    文章目录 一.源代码说明 二.字符串复制 1.STRCPY函数 2.STRNCPY函数 三.字符串拼接 1.STRCAT函数 2.STRNCAT函数 四.格式化输出到字符串 1.SPRINTF函数 2 ...

  7. Symbol - 看似平凡的Symbol其实我们每天都在用 - 字符串操作

    前言 小伙伴们大家好.前面我们分享了一篇关于对象操作的几个Symbol的内置属性.比如实例检测的Symbol.hasInstance,对象类型转换的Symbol.toPrimitive和检测数据类型的 ...

  8. [Google Guava] 2.3-强大的集合工具类:java.util.Collections中未包含的集合工具

    原文链接 译文链接 译者:沈义扬,校对:丁一 尚未完成: Queues, Tables工具类 任何对JDK集合框架有经验的程序员都熟悉和喜欢java.util.Collections包含的工具方法.G ...

  9. java工具谷歌工具-Google guava工具类的介绍和使用

    工具类 就是封装平常用的方法,不需要你重复造轮子,节省开发人员时间,提高工作效率.谷歌作为大公司,当然会从日常的工作中提取中很多高效率的方法出来.所以就诞生了guava. guava的优点: 高效设计 ...

  10. Google Guava学习笔记——基础工具类Joiner的使用

    Guava 中有一些基础的工具类,如下所列: 1,Joiner 类:根据给定的分隔符把字符串连接到一起.MapJoiner 执行相同的操作,但是针对 Map 的 key 和 value. 2,Spli ...

最新文章

  1. Python 如何计算当前时间减少或增加一个月
  2. 如何生成java_如何生成JavaAPI doc
  3. ACDSee Photo Studio Ultimate 2020中文版
  4. 数据中心气流管理的基础:密闭系统的比较
  5. mysql数据库在查询的时候不能使用字段别名,字段别名只在显示的时候显示出来
  6. POJ - 2187 Beauty Contest(最远点对)
  7. Linux内核中的常用宏container_of其实很简单【转】
  8. C++多线程编程(2) 条件变量与原子操作
  9. JSK-17 X的平方根【二分法】
  10. 材价看板(1)- 如何建立你的第一个kanban,看看这些暴露的问题你们有没有?...
  11. 信息管理软件测试工资,【用友软件工资】软件测试工程师待遇-看准网
  12. 计算机维修工具大全,电脑硬件维修测试工具大全(附送各类PC检修资源)
  13. 使用pandas比对Excel表格,把不同数据列出
  14. 网易公开课视频及字幕下载
  15. steam桌面图标空白问题解决
  16. opencv 特征提取 -SIFT
  17. 地图-导航(百度/高德)
  18. 置信区间、置信水平、边际误差
  19. 获取指定年、月的具体天数
  20. 计算机主板电池没电什么情况,主板电池没电会怎么样-电脑主板坏了会出现什么样的情况?...

热门文章

  1. ORB——OPC服务器冗余的最佳选择
  2. GM(General MIDI)128种标准音色表
  3. Swagger界面丑、功能弱怎么破?用Postman增强下就给力了!
  4. qq音乐网页版下载歌曲
  5. 百度地图自定义大头针图片和添加标注
  6. 16年“折腾史” | 盘点联想手机成与败
  7. matlab 正交特征向量,关于左右特征向量的正交性问题 求助!!!!
  8. c语言 switch case 字符串,C++ switch case详解
  9. 携程Java后台开发面经
  10. v-if和v-show的使用和特点