Google Guava之字符串处理

Google Guava之字符串处理

Google Guava依赖

<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>30.1.1-jre</version>
</dependency>

连接器[Joiner]

连接器工厂

方法 描述 范例
Joiner.on(char) 按单个字符连接 Joiner.on(’,’)
Joiner.on(CharMatcher) 按字符匹配器连接 Joiner.on(",")

连接器修饰符

方法 描述
skipNulls() 过滤字符串序列中的null值
useForNull(String) 替换字符串序列中的null值
join(Iterable) 连接对象类型的数据

用分隔符把字符串序列连接起来也可能会遇上不必要的麻烦。如果字符串序列中含有null,那连接操作会更难。Fluent风格的Joiner符串更简单。

String joinerStr = Joiner.on(";").skipNulls().join("Harry", null, "Ron", "Hermione");
//Harry;Ron;Hermione

另外,useForNull(String)方法可以给定某个字符串来替换null,而不像skipNulls()方法是直接忽略nullJoiner也可以用来连接对象类型,在这种情况下,它会把对象的toString()值连接起来。

String joinerStr = Joiner.on(";").useForNull("aries").join("Harry", null, "Ron", "Hermione");
//Harry;aries;Ron;Hermione
//User中包含age和name两个属性
User user1 = User.builder().age(18).name("张三").build();
User user2 = User.builder().age(19).name("李四").build();
String join = Joiner.on(";").join(Arrays.asList(user1, user2));
//User(age=18, name=张三);User(age=19, name=李四)

警告:joiner实例总是不可变的。用来定义joiner目标语义的配置方法总会返回一个新的joiner实例。这使得joiner实例都是线程安全的,你可以将其定义为static final常量。

拆分器[Splitter]

JDK内建的字符串拆分工具有一些古怪的特性。比如,Stringsplit()方法悄悄丢弃了尾部的分隔符。

Splitter使用令人放心的、直白的流式API模式对这些混乱的特性做了完全的掌控。

拆分器工厂

方法 描述 范例
Splitter.on(char) 按单个字符拆分 Splitter.on(‘;’)
Splitter.on(CharMatcher) 按字符匹配器拆分 Splitter.on(CharMatcher.breakingWhitespace())
Splitter.on(String) 按字符串拆分 Splitter.on(“, “)
Splitter.on(Pattern) Splitter.onPattern(String) 按正则表达式拆分 Splitter.onPattern(“\r\n”)
Splitter.fixedLength(int) 按固定长度拆分;最后一段可能比给定长度短,但不会为空 Splitter.fixedLength(3)

拆分器修饰符

方法 描述
omitEmptyStrings() 从结果中自动忽略空字符串
trimResults() 移除结果字符串的前导空白和尾部空白
trimResults(CharMatcher) 给定匹配器,移除结果字符串的前导匹配字符和尾部匹配字符
limit(int) 限制拆分出的字符串数量
split(final CharSequence) 拆分结果为Iterable
splitToList(CharSequence) 拆分结果为List
List<String> splitList = Splitter.on(',')
                .trimResults()
                .omitEmptyStrings()
                .splitToList("apple,watermelon,,    banana");
//[apple, watermelon, banana]

注:splitter实例总是不可变的。用来定义splitter目标语义的配置方法总会返回一个新的splitter实例,这使得splitter实例都是线程安全的,你可以将其定义为static final常量。

字符匹配器[CharMatcher]

在以前的Guava版本中,StringUtil类疯狂地膨胀,其拥有很多处理字符串的方法:allAscii、collapse、collapseControlChars、collapseWhitespace、indexOfChars、lastIndexNotOf、numSharedChars、removeChars、removeCrLf、replaceChars、retainAllChars、strip、stripAndCollapse、stripNonDigits。 所有这些方法指向两个概念上的问题:

  1. 怎么才算匹配字符?
  2. 如何处理这些匹配字符?

为了收拾这个泥潭,我们开发了CharMatcher。

直观上,你可以认为一个CharMatcher实例代表着某一类字符,如数字或空白字符。事实上来说,CharMatcher实例就是对字符的布尔判断—CharMatcher确实也实现了Predicate—但类似”所有空白字符”或”所有小写字母”的需求太普遍了,Guava因此创建了这一API。

然而使用CharMatcher的好处更在于它提供了一系列方法,让你对字符作特定类型的操作:修剪[trim]、折叠[collapse]、移除[remove]、保留[retain]等等。这样的设计使得API复杂度的线性增加可以带来灵活性和功能两方面的增长。

获取字符匹配器

获取字符匹配器的常见方法包括:

方法 描述
any() 匹配任何字符
none() 不匹配所有字符
whitespace() 匹配所有空白字符
breakingWhitespace() 匹配所有可换行的空白字符(不包括非换行空白字符,例如"\u00a0")
invisible() 匹配所有看不见的字符
digit() 匹配ASCII数字
javaLetter() 匹配字母
javaDigit() 匹配UNICODE数字
javaLetterOrDigit() 匹配数字或字母
javaIsoControl() 匹配ISO控制字符(制表符、回车、换行等)
javaLowerCase() 匹配小写
javaUpperCase() 匹配大写
ascii() 匹配ASCII字符
singleWidth() 匹配单字宽字符, 如中文字就是双字宽
anyOf(CharSequence) 枚举匹配字符。如CharMatcher.anyOf(“aeiou”)匹配小写英语元音
is(char) 给定单一字符匹配
inRange(char, char) 给定字符范围匹配,如CharMatcher.inRange(‘a’,‘z’)
negate() 返回以当前Matcher判断规则相反的Matcher
and(CharMatcher) 返回与其他匹配条件组合来做与判断的Matcher
or(CharMatcher) 返回与其他匹配条件组合来做或判断的Matcher

使用字符匹配器

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

方法 描述
collapseFrom(CharSequence,char) 把每组连续的匹配字符替换为特定字符。如whitespace().collapseFrom(str,';')把字符串中的连续空白字符替换为";"
matchesAllOf(CharSequence) 测试是否字符序列中的所有字符都匹配
removeFrom(CharSequence) 从字符序列中移除所有匹配字符
retainFrom(CharSequence) 在字符序列中保留匹配字符,移除其他字符
trimFrom(CharSequence) 移除字符序列的前导匹配字符和尾部匹配字符
replaceFrom(CharSequence,CharSequence) 用特定字符序列替代匹配字符
trimAndCollapseFrom(CharSequence,char) 去除两端的空格,并把中间连续的匹配字符替换为特定字符

所有这些方法返回String,除了matchesAllOf()返回的是boolean

String str = "abc\td123  ABC";

//移除control字符
String noControl = CharMatcher.javaIsoControl().removeFrom(str); 
//abcd123  ABC

//只保留数字字符
String theDigits = CharMatcher.digit().retainFrom(str);
//123

//去除两端的空格,并把中间的连续空格替换成";"(\t也会被当做空格)
String spaced = CharMatcher.whitespace().trimAndCollapseFrom(str, ';');
//abc;d123;ABC

//用*号替换所有数字
String noDigits = CharMatcher.javaDigit().replaceFrom(str, "*");
//abc	d***  ABC

// 只保留数字和小写字母
String lowerAndDigit = CharMatcher.javaDigit().or(CharMatcher.javaLowerCase()).retainFrom(str);
//abcd123

注:CharMatcher只处理char类型代表的字符;它不能理解0x10000到0x10FFFF的Unicode 增补字符。这些逻辑字符以代理对[surrogate pairs]的形式编码字符串,而CharMatcher只能将这种逻辑字符看待成两个独立的字符。

字符集[Charsets]

不要这样做字符集处理:

String str = "abc";
try {
    
    
    byte[] bytes = str.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
    
    
    throw new AssertionError(e);
}

试试这样写:

byte[] bytes = string.getBytes(Charsets.UTF_8);

Charsets针对所有Java平台都要保证支持的六种字符集提供了常量引用。尝试使用这些常量,而不是通过名称获取字符集实例。

大小写格式[CaseFormat]

CaseFormat被用来方便地在各种ASCII大小写规范间转换字符串—比如,编程语言的命名规范。CaseFormat支持的格式如下:

格式 描述 范例
LOWER_CAMEL Java变量的命名规则,如“lowerCamel” lowerCamel
LOWER_HYPHEN 连字符连接变量的命名规则,如“lower-hyphen” lower-hyphen
LOWER_UNDERSCORE C ++变量命名规则,如“lower_underscore” lower_underscore
UPPER_CAMEL Java和C++类的命名规则,如“UpperCamel” UpperCamel
UPPER_UNDERSCORE Java和C++常量的命名规则,如“UPPER_UNDERSCORE” UPPER_UNDERSCORE

CaseFormat的用法很直接:

String to(CaseFormat format, String str):从这一格式指定格式的指定字符串str转换

//常量命名规则转换小驼峰命名规则
CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, "CONSTANT_NAME");
//constantName

我们CaseFormat在某些时候尤其有用,比如编写代码生成器的时候。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44191814/article/details/120188804