点赞再看,威力无限。微信搜索“程序猿艾伦”。本文已收录在Github.com/niumoo/JavaNotes和UnreadCodeBlog,有很多知识点和系列文章。在日常的Java开发中,由于JDK无法提供足够的常用操作库,我们通常会引入ApacheCommonsLang工具库或者GoogleGuava工具库来简化开发过程。两个类库都为java.langAPI提供了很多实用的工具,比如常用的字符串操作、基本数值操作、时间操作、对象反射、并发操作等。org.apache.commonscommons-lang33.12.0不过最近在使用ApacheCommonsLang工具库的时候踩了个坑,导致程序出现意想不到的结果。StringUtils.split这个坑也是因为踩了这个坑,所以干脆写了一篇文章介绍ApacheCommonsLang工具库中字符串操作相关的API。先说坑吧。我们都知道String类中的split方法可以拆分一个字符串。比如字符串aabbccdd按照bc拆分结果应该是aab和cdd。这样的结果也很容易验证。Stringstr="aabbccdd";for(Strings:str.split("bc")){System.out.println(s);}//结果aabcdd可能是String类中的split方法,我一直以为StringUtils.split的效果应该是一样的,结果完全不一样。可以尝试分析以下三种方式的输出结果。StringUtils是CommonsLang类库中的一个字符串工具类。publicstaticvoidtestA(){Stringstr="aabbccdd";String[]resultArray=StringUtils.split(str,"bc");for(Strings:resultArray){System.out.println(s);}}i上面testA方法的期望是aab和cdd,但实际上这个方法的结果是://testA输出aadd,可以看到字母b和c没有了,只剩下a和b,这是已经发现的问题是的,查看源码后发现StringUtils.split方法实际上是对字符进行操作的,并没有将拆分后的字符串作为一个整体来查看,返回结果中不包含使用的字符分裂。验证码:publicstaticvoidtestB(){Stringstr="abc";String[]resultArray=StringUtils.split(str,"ac");for(Strings:resultArray){System.out.println(s);}}//testB输出bpublicstaticvoidtestC(){Stringstr="abcd";String[]resultArray=StringUtils.split(str,"ac");for(Strings:resultArray){System.out.println(s);}}//testC输出bd输出与预期一致。StringUtils.split源码分析点开源代码一目了然,发现在方法注释中已经提示:返回的字符串数组不包含分隔符。分隔符不包含在返回的String数组中。相邻的分隔符被视为一个分隔符。为了更好地控制拆分,请使用StrTokenizer类....继续跟踪源代码,可以看到最终拆分在拆分字符串时有四个输入参数。privatestaticString[]splitWorker(finalStringstr,//原始字符串finalStringseparatorChars,//separatorfinalintmax,//拆分后返回多少个结果,-1都是finalbooleanpreserveAllTokens//暂不关心){}根据分隔符的不同分为三种情况。1.分隔符为nullfinalintlen=str.length();if(len==0){returnArrayUtils.EMPTY_STRING_ARRAY;}finalListlist=newArrayList<>();intsizePlus1=1;inti=0;intstart=0;booleanmatch=false;booleanlastMatch=false;if(separatorChars==null){//空分隔符意味着使用空格while(i=0){//包含判断if(match||preserveAllTokens){如何解决?1.使用splitByWholeSeparator方法。我们想要的是按整个字符串拆分。StringUtils工具类中已经有具体实现,使用splitByWholeSeparator方法。Stringstr="aabbccdd";String[]resultArray=StringUtils.splitByWholeSeparator(str,"bc");for(Strings:resultArray){System.out.println(s);}//输出aabcdd2。使用GoogleGuava工具库关于Guava工具库的使用,之前写过一篇文章,可以参考:Guava-节省垃圾代码Stringstr="aabbccdd";Iterableiterable=Splitter.on("bc").omitEmptyStrings()//忽略空值.trimResults()//过滤结果中的空白.split(str);iterable.forEach(System.out::println);//输出aabcdd3.JDK的String.split方法可以使用String中的split方法达到预期的效果。Stringstr="aabbccdd";String[]res=str.split("bc");for(Stringre:res){System.out.println(re);}//输出aabcdd但是String的split方法也有一些坑,比如下面的输出结果。Stringstr=",a,,b,";String[]splitArr=str.split(",");Arrays.stream(splitArr).forEach(System.out::println);//输出逗号处ab开头,前面有一个空格,但是结尾的逗号后面没有空格。一如既往,文章中的代码保存在Github.com/niumoo/javaNotes。<完>文章持续更新中,可微信搜索“程序猿Alan”或访问“程序猿阿郎博客”立即阅读.本文已收录于Github.com/niumoo/JavaNotes。知识点多,系列文章多。欢迎来到星空。