Guava字符串操作
在Java开发的道路上,我们经常会面临各种各样的字符串处理任务,从简单的判空到复杂的拆分和连接操作。为了简化这些常见但有时繁琐的任务,Google推出了一款强大的Java库------Guava。Guava不仅为我们提供了丰富的集合工具,还包括了许多方便而高效的字符串处理工具。
在本文中,我们将专注于探讨Guava库中关于字符串操作的强大功能。无论您是正在寻找更好的字符串拆分方法,还是希望提高代码的可读性和性能,Guava都为您提供了解决方案。
本文内容参考:Guava操作字符串
一、连接器【Joiner】
Joiner是字符串连接器,可以处理字符串中的null值,简洁方便。
1、常用方法:
方法名称 | 描述 | 范例 |
---|---|---|
skipNulls() | 跳过空值 | |
useForNull(String) | 使用参数替换字符串中的null值 | |
withKeyValueSeparator(String) | 使用参数连接map结构 |
2、Joiner的使用分为三个步骤:
(1)、on方法用来设置链接符
(2)、在on方法之后 join方法之前 ,我们可以做一些扩展操作,比如s使用useForNull是为null值设置默认值。
(3)、join方法用来设置被操作的集合
3、使用示例:
csharp
@Test
public void joinerTest(){
List<String> list = Lists.newArrayList("Hello",null,"World","!");
// skipNulls
Joiner joiner = Joiner.on(" ").skipNulls();
System.out.println(joiner.join(list));
// useForNull
joiner = Joiner.on(" ").useForNull("My");
System.out.println(joiner.join(list));
// withKeyValueSeparator
Map<String, String> map = ImmutableMap.of("a","1","b","2");
System.out.println(Joiner.on(";").withKeyValueSeparator("-").join(map));
}
注:joiner实例总是不可变的。用来定义joiner目标语义的配置方法总会返回一个新的joiner实例。这使得joiner实例都是线程安全的,你可以将其定义为static final常量。
二、字符串拆分器【Splitter】
Splitter可以被设置为按照任何模式、字符、字符串或字符匹配器拆分。返回一个Iterable
1、拆分器工厂
方法 | 描述 | 范例 |
---|---|---|
Splitter.on(Char) | 按照单个字符拆分 | Splitter.on(",") |
Splitter.on(CharMatcher) | 按字符匹配器拆分 | Splitter.on(CharMatcher.BREAKING_WHITESPACE) |
Splitter.on(String) | 按字符串拆分 | Splitter.on("a") |
Splitter.on(Pattern) Splitter.onPattern(String) | 按正则表达式拆分 | Splitter.onPattern("\r?\n") |
Splitter.fixedLength(int) | 按固定长度拆分;最后一段可能比给定长度短,但不会为空。 | Splitter.fixedLength(3) |
2、拆分器修饰符
方法 | 描述 |
---|---|
omitEmptyStrings() | 从结果中自动忽略空字符串 |
trimResults() | 移除结果字符串的前导空白和尾部空白 |
trimResults(CharMatcher) | 给定匹配器,移除结果字符串的前导匹配字符和尾部匹配字符 |
limit(int) | 限制拆分出的字符串数量,即只有前几个拆分符生效 |
splitToList | 将拆分接口用List返回 |
withKeyValueSeparator | 将String转换Map<String,String> |
3、示例
csharp
@Test
public void splitterTest(){
// trimResults 去掉头尾空格 |a||b|c||
List<String> splitterList = Splitter.on(",").trimResults().splitToList(" ,a,,b,c,, ");
System.out.println(Joiner.on("|").join(splitterList));
// omitEmptyStrings 忽略空串 |a|b|c|
splitterList = Splitter.on(",").omitEmptyStrings().splitToList(" ,a,,b,c,, ");
System.out.println(Joiner.on("|").join(splitterList));
// 两者一起使用 a|b|c
splitterList = Splitter.on(",").trimResults().omitEmptyStrings().splitToList(" ,a,,b,c,, ");
System.out.println(Joiner.on("|").join(splitterList));
// limit a|b,c,,
splitterList = Splitter.on(",").trimResults().omitEmptyStrings().limit(2).splitToList(" ,a,,b,c,, ");
System.out.println(Joiner.on("|").join(splitterList));
// withKeyValueSeparator a=1|b=2
Map<String, String> splitterMap = Splitter.on(";").withKeyValueSeparator("-").split("a-1;b-2");
System.out.println(Joiner.on("|").withKeyValueSeparator("=").join(splitterMap));
}
注:splitter实例总是不可变的。用来定义splitter目标语义的配置方法总会返回一个新的splitter实例。这使得splitter实例都是线程安全的,你可以将其定义为static final常量。
三、字符匹配器【CharMatcher】
直观上可以认为CharMatcher实例代表着某一类字符,如数字或空白字符。事实上来说,CharMatcher实例就是对字符的布尔判断------CharMatcher确实也实现了Predicate。
使用CharMatcher的好处更在于它提供了一系列方法,让你对字符作特定类型的操作:修剪[trim]、折叠[collapse]、移除[remove]、保留[retain]等等。CharMatcher实例首先代表概念1:怎么才算匹配字符?然后它还提供了很多操作概念2:如何处理这些匹配字符?
1、常见字符匹配器常量
常量 | 描述 |
---|---|
ANY | 匹配任何字符 |
ASCII | 匹配是否是ASCII字符 |
BREAKING_WHITESPACE | 匹配所有可换行的空白字符(不包括非换行空白字符,例如"\u00a0") |
DIGIT | 匹配ASCII数字 |
INVISIBLE | 匹配所有看不见的字符 |
JAVA_DIGIT | 匹配UNICODE数字, 使用 Character.isDigit() 实现 |
JAVA_ISO_CONTROL | 匹配ISO控制字符, 使用 Charater.isISOControl() 实现 |
JAVA_LETTER | 匹配字母, 使用 Charater.isLetter() 实现 |
JAVA_LETTER_OR_DIGET | 匹配数字或字母 |
JAVA_LOWER_CASE | 匹配小写 |
JAVA_UPPER_CASE | 匹配大写 |
NONE | 不匹配所有字符 |
SINGLE_WIDTH | 匹配单字宽字符, 如中文字就是双字宽 |
WHITESPACE | 匹配所有空白字符 |
2、常用操作方法
java
CharMatcher is(char match): //返回匹配指定字符的Matcher
CharMatcher isNot(char match): //返回不匹配指定字符的Matcher <br />
CharMatcher anyOf(CharSequence sequence): //返回匹配sequence中任意字符的Matcher
CharMatcher noneOf(CharSequence sequence): //返回不匹配sequence中任何一个字符的Matcher
**CharMatcher inRange(char startInclusive, char endInclusive): //返回匹配范围内任意字符的Matcher
CharMatcher forPredicate(Predicate<? super Charater> predicate): //返回使用predicate的apply()判断匹配的Matcher
CharMatcher negate(): //返回以当前Matcher判断规则相反的Matcher <br />
**CharMatcher and(CharMatcher other): //返回与other匹配条件组合做与来判断的Matcher
**CharMatcher or(CharMatcher other): //返回与other匹配条件组合做或来判断的Matcher
boolean matchesAnyOf(CharSequence sequence): //只要sequence中有任意字符能匹配Matcher,返回true
boolean matchesAllOf(CharSequence sequence): //sequence中所有字符都能匹配Matcher,返回true
boolean matchesNoneOf(CharSequence sequence): //sequence中所有字符都不能匹配Matcher,返回true
int indexIn(CharSequence sequence): //返回sequence中匹配到的第一个字符的坐标
int indexIn(CharSequence sequence, int start): //返回从start开始,在sequence中匹配到的第一个字符的坐标
int lastIndexIn(CharSequence sequence): //返回sequence中最后一次匹配到的字符的坐标
int countIn(CharSequence sequence): //返回sequence中匹配到的字符计数
**String removeFrom(CharSequence sequence): //删除sequence中匹配到到的字符并返回
**String retainFrom(CharSequence sequence): //保留sequence中匹配到的字符并返回
**String replaceFrom(CharSequence sequence, char replacement): //替换sequence中匹配到的字符并返回
**String trimFrom(CharSequence sequence): //删除首尾匹配到的字符并返回
**String trimLeadingFrom(CharSequence sequence): //删除首部匹配到的字符
**String trimTrailingFrom(CharSequence sequence): //删除尾部匹配到的字符
**String collapseFrom(CharSequence sequence, char replacement): //将匹配到的组(连续匹配的字符)替换成replacement
**String trimAndCollapseFrom(CharSequence sequence, char replacement): //先trim在replace>
3、示例:
less
@Test
public void charMatcherTest(){
String testStr = "FirstName LastName +1 123 456 789 !@#$%^&*()_+|}{:"?><";
System.out.println(CharMatcher.digit().retainFrom(testStr));// 1123456789
System.out.println(CharMatcher.javaLetter().retainFrom(testStr));// FirstNameLastName
System.out.println(CharMatcher.javaLetterOrDigit().retainFrom(testStr)); // FirstNameLastName1123456789
System.out.println(CharMatcher.javaLowerCase().retainFrom(testStr)); // irstameastame
System.out.println(CharMatcher.any().countIn(testStr));// 54
System.out.println(CharMatcher.inRange('0','9').retainFrom(testStr));// 1123456789
System.out.println(CharMatcher.inRange('0','9').removeFrom(testStr));// FirstName LastName + !@#$%^&*()_+|}{:"?><
System.out.println(CharMatcher.inRange('0','9').or(CharMatcher.whitespace()).retainFrom(testStr)); // 1 123 456 789
System.out.println(CharMatcher.inRange('0','9').or(CharMatcher.anyOf("abcd")).retainFrom(testStr));// aaa1123456789
System.out.println(CharMatcher.inRange('0','9').replaceFrom(testStr,"*"));// FirstName LastName +* *** *** *** !@#$%^&*()_+|}{:"?><
}
注:CharMatcher只处理char类型代表的字符;
四、字符集【Charsets】
Charsets针对所有Java平台都要保证支持的六种字符集提供了常量引用。尝试使用这些常量,而不是通过名称获取字符集实例。
示例
bytes = string.getBytes(Charsets.UTF_8);
五、大小写格式【CaseFormat】
CaseFormat被用来方便地在各种ASCII大小写规范间转换字符串------比如,编程语言的命名规范。CaseFormat支持的格式如下:
格式 | 范例 |
---|---|
LOWER_CAMEL | lowerCamel |
LOWER_HYPHEN | lower-hyphen |
LOWER_UNDERSCORE | lower_underscore |
UPPER_CAMEL | UpperCamel |
UPPER_UNDERSCORE | UPPER_UNDERSCORE |
示例:
csharp
@Test
public void caseFormatTest(){
System.out.println(CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL,"FIRSTNAME"));// firstname
}
总结
在使用Guava字符串处理工具时,性能是一个不可忽视的因素。Guava库经过精心设计,旨在提供高效的操作,但在一些特定场景下,合理的性能考虑仍然是必要的。
首先,Guava的字符串处理工具通常在处理大规模数据时表现出色。例如,在使用Splitter
进行字符串拆分时,Guava能够更有效地处理大型字符串,相较于传统的字符串拆分方法,这将在处理大量文本数据时体现出明显的性能优势。
其次,Guava的一些设计目标是为了避免不必要的内存分配和拷贝,从而提高性能。例如,使用Joiner
连接字符串时,Guava可以更智能地处理拼接过程,减少临时对象的创建,从而降低了内存开销。然而,在某些场景下,如果性能是关键问题,开发者仍需谨慎选择适当的方法和工具。Guava提供了丰富的选项,通过合理地选择工具和参数,可以使得性能得到最优化。
Guava字符串处理工具为Java开发者提供了强大而灵活的解决方案,能够简化日常的字符串操作,并在性能方面展现出色的表现。通过本文的介绍,我们深入了解了Guava中关于字符串的各种特性,从基础的判空和拆分,到高级的不可变字符串。
在使用Guava时,我们学习了如何利用Splitter
和Joiner
等工具执行各种字符串操作,以及如何通过CharMatcher
处理字符匹配和替换。同时,我们也了解了不可变字符串的优势,以及在一些特定场景中的应用。
在选择使用Guava字符串处理工具时,我们需要根据具体的需求和场景来权衡灵活性和性能。Guava为我们提供了丰富的选择,让我们在处理字符串时更加便捷高效。
总的来说,Guava的字符串处理工具不仅为我们提供了更好的开发体验,同时也通过其高效的设计为项目性能提供了可靠的支持。在今后的Java开发中,深入了解并灵活应用Guava的字符串处理工具,将是提高代码质量和开发效率的不错选择。