Guava官方文档中文版(七)-字符串工具

字符串工具

Joiner

用分隔符将一序列字符串连接到一起可能会有不必要的麻烦 – 但是不应该这样。如果你的序列包含null,它可能更加困难。Joiner的流式风格简化这些操作。

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

返回字符串“Harry; Ron; Hermione”。或者,使用skipNulls代替,你可以指定一个字符串来使用useForNull(String)代替null。

你也可以在对象上使用Joiner,他们将使用他们的toString进行转换并进行连接。

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

警告:Joiner实例总是不可变的。joiner配置方法总是返回一个新的Joiner,你必须使用它获取所需的语义。这使任何Joiner线程安全,并且可用作static final常量。

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");

返回一个Iterable<String>,其包含"foo", “bar”, “qux”。Splitter可以被设置依据任何PatterncharStringCharMatcher上进行分割。

基本工厂
方法描述示例
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)
修饰符
方法描述示例
omitEmptyStrings()自动忽略结果的空字符串Splitter.on(',').omitEmptyStrings().split("a,,c,d")返回"a", "c", "d"
trimResults()减去结果的头尾空白符;等价于trimResults(CharMatcher.WHITESPACE)Splitter.on(',').trimResults().split("a, b, c, d")返回"a", "b", "c", "d"
trimResults(CharMatcher)减去结果匹配指定的CharMatcher的头尾Splitter.on(',').trimResults(CharMatcher.is('_')).split("_a ,_b_ ,c__")返回"a ", "b_ ", "c"
limit(int)返回了指定数量的字符串后停止分割Splitter.on(',').limit(3).split("a,b,c,d")返回"a", "b", "c,d"

如果你希望得到List,使用splitToList()代替split()

警告:分割器实例总是不可变的。分割器配置方法总是返回一个新的Splitter,你必须使用它来获取所需的语义。这使任何Splitter线程安全,可用作为static final常量。

Map Splitters

你也可以使用一个splitter来反序列化一个map,通过使用withKeyValueSeparator()指定第二个分隔符。作为结果的MapSplitter使用splitter的分隔符将输入分割为条目(entry),然后使用给定的key-value分割器将这些条目分割到key和value,返回Map<String, String>

CharMatcher

在早期,我们的StringUtil类不受约束地发展,有许多像以下这样的方法:

  • allAscii
  • collapse
  • collapseControlChars
  • collapseWhitespace
  • lastIndexNotOf
  • numSharedChars
  • removeChars
  • removeCrLf
  • retainAllChars
  • strip
  • stripAndCollapse
  • stripNonDigits

他们表示了两个概念的交集:

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

为了简化这个困境,我们开发了CharMatcher

直观地,你可以想象CharMatcher作为表示一个特别的字符类,就像数字或者空格。实际上来说,CharMatcher仅仅是在字符上的布尔(boolean)条件 – 实际上,CharMatcher实现了Predicate<Character> – 但是因为它通常适用于“所有空白字符”或者“所有小写字母”,Guava针对字符提供了特殊化语法和API。

但是CharMatcher的效用是它允许你在指定类型的字符的出现执行操作:剔除(trimming),压缩(collapsing),移除(removing),保留(retaining)和更多操作。类型CharMatcher对象表示概念1:什么构成了匹配字符串?然后它给出了很多回答概念2的操作:如何处理这些匹配字符串?结果是API的复杂性呈直线上升,灵活性和功能成倍增加。Yay!

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值;它不会理解附加附加在0x10000到0x10FFFF的Unicode代码点。这样的逻辑字符串使用代理对的方式编码到String,CharMatcher将这些仅视为两个分隔的字符。

获取CharMatcher

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

其他获取CharMatcher常用的方式包括:

方法描述
anyOf(CharSequence)指定所有你希望匹配的字符。例如,CharMatcher.anyOf("aeiou")匹配小写英文元音
is(char)精确指定匹配的一个字符
inRange(char, char)指定匹配的范围字符,即:CharMatcher.inRange('a', 'z')

或者,CharMatchernegate(),and(CharMatcher)or(CharMatcher)。这些提供关于CharMatcher的布尔操作。

使用CharMatcher

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。)

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平台实现支持。使用他们代替根据他们名称的字符编码引用。

TODO:charset说明和什么时候使用他们
(**注意:**如果你使用JDK7,你应该使用在StandardCharsets中的常量。)

CaseFormat

CaseFormat是一个用于ASCII大小写约定之间进行转换的小巧的类–例如,程序语言命名规范。支持的格式包含:

格式示例
LOWER_CAMELlowerCamel
LOWER_HYPHENlower-hyphen
LOWER_UNDERSCORElower_underscore
UPPER_CAMELUpperCamel
UPPER_UNDERSCOREUPPER_UNDERSCORE

使用它是相对简单的:

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

我们发现这个特别有用,例如,当写生成其他程序的程序时。

Strings

存在于Strings类中有限数量的通用目的的String工具。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值