




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第java开发使用StringUtils.split避坑详解目录正文StringUtils.split的坑StringUtils.split源码分析如何解决?
正文
在日常的Java开发中,由于JDK未能提供足够的常用的操作类库,通常我们会引入ApacheCommonsLang工具库或者GoogleGuava工具库简化开发过程。两个类库都为java.langAPI提供了很多实用工具,比如经常使用的字符串操作,基本数值操作、时间操作、对象反射以及并发操作等。
dependency
groupIdmons/groupId
artifactIdcommons-lang3/artifactId
version3.12.0/version
/dependency
但是,最近在使用ApacheCommonsLang工具库时踩了一个坑,导致程序出现了意料之外的结果。
StringUtils.split的坑
也是因为踩了这个坑,索性写下一篇文章好好介绍下ApacheCommonsLang工具库中字符串操作相关API。
先说坑是什么,我们都知道String类中到的split方法可以分割字符串,比如字符串aabbccdd根据bc分割的结果应该是aab和cdd才对,这样的结果也很容易验证。
Stringstr="aabbccdd";
for(Strings:str.split("bc")){
System.out.println(s);
//结果
可能是因为String类中的split方法的影响,我一直以为StringUtils.split的效果应该相同,但其实完全不同,可以试着分析下面的三个方法输出结果是什么,StringUtils是CommonsLang类库中的字符串工具类。
publicstaticvoidtestA(){
Stringstr="aabbccdd";
String[]resultArray=StringUtils.split(str,"bc");
for(Strings:resultArray){
System.out.println(s);
我对上面testA方法的预期是aab和cdd,但是实际上这个方法的运行结果是:
//testA输出
aa
dd
可以看到b和c字母都不见了,只剩下了a和b,这是已经发现问题了,查看源码后发现StringUtils.split方法其实是按字符进行操作的,不会把分割字符串作为一个整体来看,返回的结果中不也会包含用于分割的字符。
验证代码:
publicstaticvoidtestB(){
Stringstr="abc";
String[]resultArray=StringUtils.split(str,"ac");
for(Strings:resultArray){
System.out.println(s);
//testB输出
publicstaticvoidtestC(){
Stringstr="abcd";
String[]resultArray=StringUtils.split(str,"ac");
for(Strings:resultArray){
System.out.println(s);
//testC输出
输出结果和预期的一致了。
StringUtils.split源码分析
点开源码一眼看下去,发现在方法注释中就已经进行提示了:返回的字符串数组中不包含分隔符。
TheseparatorisnotincludedinthereturnedStringarray.Adjacentseparatorsaretreatedasoneseparator.FormorecontroloverthesplitusetheStrTokenizerclass....
继续追踪源码,可以看到最终split分割字符串时入参有四个。
privatestaticString[]splitWorker(
finalStringstr,//原字符串
finalStringseparatorChars,//分隔符
finalintmax,//分割后返回前多少个结果,-1为所有
finalbooleanpreserveAllTokens//暂不关注
根据分隔符的不同又分了三种情况。
1.分隔符为null
finalintlen=str.length();
if(len==0){
returnArrayUtils.EMPTY_STRING_ARRAY;
finalListStringlist=newArrayList();
intsizePlus1=1;
inti=0;
intstart=0;
booleanmatch=false;
booleanlastMatch=false;
if(separatorChars==null){
//Nullseparatormeansusewhitespace
while(ilen){
if(Character.isWhitespace(str.charAt(i))){
if(match||preserveAllTokens){
lastMatch=true;
if(sizePlus1++==max){
i=len;
lastMatch=false;
list.add(str.substring(start,i));
match=false;
start=++i;
continue;
lastMatch=false;
match=true;
i++;
//...
if(match||preserveAllTokenslastMatch){
list.add(str.substring(start,i));
可以看到如果分隔符为null,是按照空白字符Character.isWhitespace()分割字符串的。分割的算法逻辑为:
a.用于截取的开始下标置为0,逐字符读取字符串。
b.碰到分割的目标字符,把截取的开始下标到当前字符之前的字符串截取出来。
c.然后用于截取的开始下标置为下一个字符,等到下一次使用。
d.继续逐字符读取字符串、
2.分隔符为单个字符
逻辑同上,只是判断逻辑Character.isWhitespace()变为了指定字符判断。
//Optimise1charactercase
finalcharsep=separatorChars.charAt(0);
while(ilen){
if(str.charAt(i)==sep){//直接比较
3.分隔符为字符串
总计逻辑同上,只是判断逻辑变为包含判断。
//standardcase
while(ilen){
if(separatorChars.indexOf(str.charAt(i))=0){//包含判断
if(match||preserveAllTokens){
如何解决?
1.使用splitByWholeSeparator方法。
我们想要的是按整个字符串分割,StringUtils工具类中已经存在具体的实现了,使用splitByWholeSeparator方法。
Stringstr="aabbccdd";
String[]resultArray=StringUtils.splitByWholeSeparator(str,"bc");
for(Strings:resultArray){
System.out.println(s);
//输出
2.使用GoogleGuava工具库
关于Guava工具库的使用,之前也写过一篇文章,可以参考:Guava-拯救垃圾代码
Stringstr="aabbccdd";
IterableStringiterable=Splitter.on("bc")
.omitEmptyStrings()//忽略空值
.trimResults()//过滤结果中的空白
.split(str);
iterable.forEach(System.out::println);
//输出
3.JDKString.split方法
使用String中的split方法可以实现想要效果。
Stringstr="aabbccdd";
String[]res=str.split("bc");
for(Stringre:res){
System.out.println(re);
//输出
但是String的split方法也有一些坑,比如下面的输出结果。
Stringstr=",a,,b,";
String[]splitArr=str.spli
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 植物新品种权转让与农业知识产权保护协议
- 股权激励与公司战略目标同步合作协议
- 子女意外伤害医疗报销分割协议
- 智能家居系统研发与市场推广合作合同
- 知识产权税费减免政策解析及实施合同
- 危险化学品生产企业安全员劳动合同
- 桥梁抗震支架安装及后期养护合作协议
- 知识产权分割与知识产权保护及运营协议
- 医疗器械临床试验项目临床研究资料保密协议
- 子女婚嫁事宜协商及财产分配协议
- 【MOOC】英语口语进阶-南京大学 中国大学慕课MOOC答案
- 新《行政处罚法》亮点ppt解读
- DB35T 2092-2022 高速公路边坡工程养护技术规范
- GB/T 29531-2013泵的振动测量与评价方法
- VSM(价值流图中文)课件
- 上海交通大学医学院附属仁济医院-日间手术管理信息化实践与发展
- 有源、无源滤波器实验报告
- SWOT分析法很全面课件
- 供应室手工清洗操作流程课件
- 消防应急疏散演练人员签到表(标准通用版)
- 数据中心基础设施管理系统DCIM整体方案
评论
0/150
提交评论