Java中String对象的Split方法分析

        关于Split我们都知道是用于切割字符串的,最近一朋友问我如果两个字符之间有两个空格,那通过一个空格去切会切成一个多大的数组,我几乎毫不犹豫的说两个,我的想法是这样的,当我们把所有空格都"切"出来,当遇到连续两个空格的时候,因为两个空格切去后中间是没有任何字符串的,我就臆想着Java肯定就会做相关的优化把"两个空格中的空字符串"去掉(之后发现并没有这样的处理),然后,嗯...就切成两个╮(-_-)╭

        然而现实却把我啪啪的打了一顿,先上一个我写的小Demo

        运行之后的结果,居然是

        跟我预想的有点不一样。感觉他的切和我想象中的切有很大的区别,然后我只能跑去看了波源码,看看Split到底是如何实现切割的,首先上面写的小Demo中的Split方法首先是调用

这里是进行了方法重载,接着调用:

     这个方法有两个参数一个String用于匹配要切的字段,另一个int类型的limit是要切成的数组的大小

    初始化一个char类型变量ch,主要用于if条件中的判断使用主要是让所切字段是一个字符的情况进行处理,其他的转到正则中进行切割,转正则在这里就不讨论了!首先对if中的条件进行整理,因为就这样看有点头晕:

     (

            (regex.value.length == 1  &&  ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||

            (regex.length() == 2 &&regex.charAt(0) == '\\' && (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&((ch-'a')|('z'-ch)) < 0 &&((ch-'A')|('Z'-ch)) < 0))

      )&&

    (

            ch < Character.MIN_HIGH_SURROGATE || ch > Character.MAX_LOW_SURROGATE

     )

    好了,大概就是这样一个结构!

    红色部分就是限定当传入的String长度是1的时候,而且这个字符不能是 . $ | ( ) [ { ^ ? * + \ 中的一个

    当传入的String大小为2时,他第一个字符必须为转义字符 \ ,而且蓝色部分表示第二个字符必须是0-9 a-z A-Z

    当上面两个条件中满足一个的时候,如果满足绿色条件,就能进入if代码块了,绿色条件限定字符是一个UTF-16(\uD800-\uDFFF)范围的字符都可以(具体原因:UTF-16比起UTF-8,好处在于大部分字符都以固定长度的字节 (2字节) 储存,但UTF-16却无法兼容于ASCII编码。

    if块内首先初始化三个标志   off标志返回数组元素的切割过程中的起始点   next标志着下一个匹配要切字段的索引    limited标志是不是要返回固定的数组大小(根据limit判断)然后定义一个有序数组集合;当有匹配就进入while循环,并且把next重新赋上第一个匹配上字符的索引!

    接下来if判断这次循环完后有没有到达limit所要求的长度,如果没有的话,就进if块里面list.add(substring(off, next));   就切索引off(包括)到next(不包括)之间的字段并保存到ArrayList中,然后off=next+1; 跳过要切的部分!(所以上面Demo中,两个空格导致的最终是进行了一个substring(第一个空格+1,第二个空格),两个参数相等,返回空串)接下来继续循环;如果if语句中判断差一个(limit-1)到要求长度,就到else中把接下来所有的字段保存在最后一个list中!

    当在while中循环完成后,首先没指定固定长度的和字段完全按照传入参数进行切割的数组大小小与要求返回大小(limit)的情况没有进入else中进行结尾操作,所以后面进行了一步结尾操作

    if (!limited || list.size() < limit)
                list.add(substring(off, value.length));

还有在while条件中没有一个匹配情况下直接放回原数组

    if (off == 0)
                return new String[]{this};

然后就对结尾的空格进行去除(并没有对中间的元素为空的进行去除,我想多了。。。)转数组 返回,大概就是这样

    int resultSize = list.size();
    if (limit == 0) {
           while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {
                resultSize--;
            }
     }
     String[] result = new String[resultSize];

     return list.subList(0, resultSize).toArray(result);

所以,由此可得,当两个空格然后用空格去切的时候,是会切出一个空串的(substring两个参数相同就返回空串),当然前提是不再最后,因为最后的空串会被去除,像如果被切字符串是##,用#去切,最终数组长度为0。



(技术文章,难免错误,望批评指正,不胜感激)





       

    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值