拥抱Guava之字符串操作

Guava字符串操作

在Java开发的道路上,我们经常会面临各种各样的字符串处理任务,从简单的判空到复杂的拆分和连接操作。为了简化这些常见但有时繁琐的任务,Google推出了一款强大的Java库——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、使用示例:
@Test
public void joinerTest(){List<String> list = Lists.newArrayList("Hello",null,"World","!");// skipNullsJoiner joiner = Joiner.on(" ").skipNulls();System.out.println(joiner.join(list));// useForNulljoiner = Joiner.on(" ").useForNull("My");System.out.println(joiner.join(list));// withKeyValueSeparatorMap<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<T>

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、示例
 @Testpublic 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|csplitterList = 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=2Map<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<Character>。

使用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、常用操作方法
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、示例:
@Test
public void charMatcherTest(){String testStr = "FirstName LastName +1 123 456 789 !@#$%^&*()_+|}{:\"?><";System.out.println(CharMatcher.digit().retainFrom(testStr));// 1123456789System.out.println(CharMatcher.javaLetter().retainFrom(testStr));// FirstNameLastNameSystem.out.println(CharMatcher.javaLetterOrDigit().retainFrom(testStr)); // FirstNameLastName1123456789System.out.println(CharMatcher.javaLowerCase().retainFrom(testStr)); // irstameastameSystem.out.println(CharMatcher.any().countIn(testStr));// 54System.out.println(CharMatcher.inRange('0','9').retainFrom(testStr));// 1123456789System.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 789System.out.println(CharMatcher.inRange('0','9').or(CharMatcher.anyOf("abcd")).retainFrom(testStr));// aaa1123456789System.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_CAMELlowerCamel
LOWER_HYPHENlower-hyphen
LOWER_UNDERSCORElower_underscore
UPPER_CAMELUpperCamel
UPPER_UNDERSCOREUPPER_UNDERSCORE
示例:
@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的字符串处理工具,将是提高代码质量和开发效率的不错选择。

本文已收录于我的个人博客:码农Academy的博客,专注分享Java技术干货,包括Java基础、Spring Boot、Spring Cloud、Mysql、Redis、Elasticsearch、中间件、架构设计、面试题、程序员攻略等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/611846.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python线程池提交任务

1. 线程池参数设置 CPU数量&#xff1a;N线程池的核心线程数量 IO密集型的话&#xff0c;一般设置为 2 * N 1&#xff1b; CPU密集型的话&#xff0c;一般设置为 N 1 或者 使用进程池。线程池的最大任务队列长度 &#xff08;线程池的核心线程数 / 单个任务的执行时间&#…

LeetCode 84:柱状图中的最大矩形

一、题目描述 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: 输入&#xff1a;heights [2,1,5,6,2,3] 输出&#xff1a;10 解释&#xff1a…

Jmeter+ant+Jenkins 接口自动化框架完整版

接口自动化测试单有脚本是不够的&#xff0c;我们还需要批量跑指定接口&#xff0c;生成接口运行报告&#xff0c;定位报错接口&#xff0c;接口定时任务&#xff0c;邮件通知等功能。批量跑指定接口&#xff1a;我们可以利用ant批量跑指定目录下的Jmeter脚本生成接口运行报告&…

vue3基础类型和引用类型,和store的使用

案例一&#xff1a; 如果我在store创建一个变量&#xff0c;是读取缓存key为name的数据&#xff0c; store.name 默认值是张三 # 声明一个变量 const title ref(store.name) # 然后修改title.value "李四"&#xff0c; # 问&#xff1a;打印store.name&#xff0…

怎么投稿各大媒体网站?

怎么投稿各大媒体网站&#xff1f;这是很多写作者及自媒体从业者经常面临的问题。在信息爆炸的时代&#xff0c;如何将自己的文章推送到广大读者面前&#xff0c;成为了一个不可避免的挑战。本文将为大家介绍一种简单有效的投稿方法——媒介库发稿平台发稿&#xff0c;帮助大家…

5,sharding-jdbc入门-sharding-jdbc广播表

执行sql #在数据库 user_db、order_db_1、order_db_2中均要建表 CREATE TABLE t_dict (dict_id BIGINT (20) NOT NULL COMMENT 字典id,type VARCHAR (50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 字典类型,code VARCHAR (50) CHARACTER SET utf8 COLLAT…

国产AI工具钉钉AI助理:开启个性化助手服务的新篇章

钉钉AI助理是钉钉平台的一项功能&#xff0c;它可以根据用户的需求提供个性化的AI助手服务。用户可以在AI助理页面一键创建个性化的AI助理&#xff0c;如个人的工作AI助理、旅游AI助理、资讯AI助理等。企业也可以充分使用企业所沉淀的知识库和业务数据&#xff0c;在获得授权后…

C#入门篇(一)

变量 顾名思义就是变化的容器&#xff0c;即可以用来存放各种不同类型数值的一个容器 折叠代码 第一步&#xff1a;#region 第二步&#xff1a;按tab键 14种数据类型 有符号的数据类型 sbyte&#xff1a;-128~127 short&#xff1a;-32768~32767 int&#xff1a;-21亿多~21亿多…

pom依赖相关

一、创建可执行jars&#xff1a; 1、可执行jars&#xff1a;可执行 jars&#xff08;有时称为“fat jars”&#xff09;是包含已编译类以及代码需要运行的所有 jar 依赖项的存档。 2、方法&#xff1a;pom中添加spring-boot-maven-plugin&#xff0c;可将项目打包成可执行jar…

CHS_01.2.1.1+2.1.3+进程的概念、组成、特征

CHS_01.2.1.12.1.3进程的概念、组成、特征 进程进程的概念 进程的组成——PCB进程的组成——PCB进程的组成——程序段、数据段知识滚雪球&#xff1a;程序是如何运行的&#xff1f;进程的组成进程的特征 知识回顾与重要考点 从这个小节开始 我们会正式进入第二章处理机管理相关…

封装动画函数

文章目录 需求分析确定参数确定属性值具体实现简单扩展 需求分析 在 css 中&#xff0c;如果要给一个元素设置动画&#xff0c;就要改变一个css属性&#xff0c;也是一个值到另外一个值的变化&#xff0c;但是放入到我们这里的动画函数里面&#xff0c;我是不知道是具体要用到…

STK 特定问题建模(五)频谱分析(第二部分)

文章目录 简介三、链路分析3.1 星地链路干扰分析3.2 频谱分析 简介 本篇对卫星通信中的频谱利用率、潜在干扰对频谱的影响进行分析&#xff0c;以LEO卫星信号对GEO通信链路影响为例&#xff0c;分析星地链路频谱。 建模将从以下几个部分开展&#xff1a; 1、GEO星地通信收发机…

Java接口的解析

在 Java 中&#xff0c;接口&#xff08;Interface&#xff09;是一种抽象类型&#xff0c;用于定义一组相关方法的契约。接口只包含方法的签名&#xff0c;而没有方法的实现。实现接口的类必须提供接口中定义的方法的具体实现。 以下是对 Java 接口的解析&#xff1a; 这只是…

springboot常用扩展点

当涉及到Spring Boot的扩展和自定义时&#xff0c;Spring Boot提供了一些扩展点&#xff0c;使开发人员可以根据自己的需求轻松地扩展和定制Spring Boot的行为。本篇博客将介绍几个常用的Spring Boot扩展点&#xff0c;并提供相应的代码示例。 1. 自定义Starter(面试常问) Sp…

使用Scikit Learn 进行识别手写数字

使用Scikit Learn 进行识别手写数字 作者&#xff1a;i阿极 作者简介&#xff1a;数据分析领域优质创作者、多项比赛获奖者&#xff1a;博主个人首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可以点赞&#x1f44d;收藏&#x1f…

MySql -数据库进阶

一、约束 1.外键约束 外键约束概念 让表和表之间产生关系&#xff0c;从而保证数据的准确性&#xff01; 建表时添加外键约束 为什么要有外键约束 -- 创建db2数据库 CREATE DATABASE db2; -- 使用db2数据库 USE db2;-- 创建user用户表 CREATE TABLE USER(id INT PRIMARY KEY …

2024-01-09 Android.mk 根据c文件名插入特定的宏定义,我这里用于定义log LOG_TAG 标签

一、在Android的构建系统中&#xff0c;使用Android.mk构建脚本可以根据特定需求来定义宏。如果你想根据C文件的名称来插入特定的宏定义&#xff0c;可以使用条件语句检查文件名&#xff0c;并相应地设置宏。 在Android的构建系统中&#xff0c;使用Android.mk构建脚本可以根据…

利用邮件发送附件来实现一键巡检,附件是通过调用zabbix api生成的word和Excel

HTML部分&#xff1a; <!DOCTYPE html> <html> <head><title>自动巡检</title><!-- 加入CSS样式 --> </head> <body><form id"inspectionForm"><label for"email">邮箱地址:</label>&…

图片分类的脚本

当前有个名为“image”的文件夹和名为“label”的txt文件&#xff0c;txt文件里的每一行包含了“photos”文件夹里每一个图片文件的文件名 一个空格 对应的标签&#xff08;1、2....8&#xff09;&#xff0c;请编写一个脚本&#xff0c;并创建一个新的文件夹&#xff0c;里面…

【MySQL】表设计与范式设计

文章目录 一、数据库表设计一对一一对多多对多 二、范式设计第一范式第二范式第三范式BC范式第四范式 一、数据库表设计 一对一 举个例子&#xff0c;比如这里有两张表&#xff0c;用户User表 和 身份信息Info表。 因为一个用户只能有一个身份信息&#xff0c;所以User表和In…