Java工具类(一)Guava操作字符串

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时,我们学习了如何利用SplitterJoiner等工具执行各种字符串操作,以及如何通过CharMatcher处理字符匹配和替换。同时,我们也了解了不可变字符串的优势,以及在一些特定场景中的应用。

在选择使用Guava字符串处理工具时,我们需要根据具体的需求和场景来权衡灵活性和性能。Guava为我们提供了丰富的选择,让我们在处理字符串时更加便捷高效。

总的来说,Guava的字符串处理工具不仅为我们提供了更好的开发体验,同时也通过其高效的设计为项目性能提供了可靠的支持。在今后的Java开发中,深入了解并灵活应用Guava的字符串处理工具,将是提高代码质量和开发效率的不错选择。

相关推荐
疯狂的程序猴2 分钟前
iOS App 混淆的真实世界指南,从构建到成品 IPA 的安全链路重塑
后端
旷野说9 分钟前
为什么 MyBatis 原生二级缓存“难以修复”?
java·java-ee·mybatis
8***235512 分钟前
【wiki知识库】07.用户管理后端SpringBoot部分
java
bcbnb13 分钟前
iOS 性能测试的工程化方法,构建从底层诊断到真机监控的多工具测试体系
后端
开心就好202516 分钟前
iOS 上架 TestFlight 的真实流程复盘 从构建、上传到审核的团队协作方式
后端
小周在成长25 分钟前
Java 泛型支持的类型
后端
aiopencode25 分钟前
Charles 抓不到包怎么办?HTTPS 抓包失败、TCP 数据流异常与底层补抓方案全解析
后端
阿蔹28 分钟前
JavaWeb-Selenium 配置以及Selenim classnotfound问题解决
java·软件测试·python·selenium·测试工具·自动化
稚辉君.MCA_P8_Java30 分钟前
Gemini永久会员 C++返回最长有效子串长度
开发语言·数据结构·c++·后端·算法
Penge6661 小时前
Redis-bgsave浅析
redis·后端