String深度学习——split(1)

 一、源码解读

 做银行项目时经常有对收益、份额、清算等数据文件导入数据库操作,需要用I/O流进行数据处理。在数据处理中有步重要的操作,那就是对文件的数据进行解析。一般的数据文件采用的分割原则,统一使用“|”、“,”或者其他的约束好的分隔符进行分割。

一般通常采用String的方法split进行解析

以下是源码,通过源码发现,String中已多态的形式提供了4个方法,而split(String regex)方法只是简单的再次的调用了 split(String regex , int limit)只是默认了第二个参数limit为0;

    public String[] split(String regex) {
        return split(regex, 0);
    }

接着调用 split(String regex,int limit)方法,源码如下:

 public String[] split(String regex, int limit) {
        /* fastpath if the regex is a
         (1)one-char String and this character is not one of the
            RegEx's meta characters ".$|()[{^?*+\\", or
         (2)two-char String and the first char is the backslash and
            the second is not the ascii digit or ascii letter.
         译:
           (1)当字符串长度为1位时,判断是否是“.$|()[{^?*+\\”即正则表达式中的元字符
           (2)当字符串长度为2位时,判断第一个字符是不是反斜杠且不是数字或者字母
            满足上面条件,即按照传入的字符串进行分割成数组,反之按照正则表达式的方式分割
         */
        char ch = 0;
        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))
        {
            int off = 0;
            int next = 0;
            boolean limited = limit > 0;
            ArrayList<String> list = new ArrayList<>();
            while ((next = indexOf(ch, off)) != -1) {
                if (!limited || list.size() < limit - 1) {
                    list.add(substring(off, next));
                    off = next + 1;
                } else {    // last one
                    //assert (list.size() == limit - 1);
                    list.add(substring(off, value.length));
                    off = value.length;
                    break;
                }
            }
            // If no match was found, return this
            if (off == 0)
                return new String[]{this};

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

            // Construct result
            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);
        }
        return Pattern.compile(regex).split(this, limit);
    }

二、用法注意

上面源码中方法参数limit需要注意

1、limit为0的情况

   当我们没有传入limit参数时,自动默认limit等于0。

  当limit为0时,如果后几位为空字符串(只要满足长度为0)将自动舍去。

例如:

    @Test
    public void testSpilit() {
        String oriStr = "|1|2|3|4|||";
        String[] arr = oriStr.split("\\|");

    }

   结果:

2、limit为-1的情况

返回已分割的最大长度。

例如:

    @Test
    public void testSpilit() {
        String oriStr = "|1|2|3|4|||";
        String[] arr = oriStr.split("\\|",-1);

    }

结果如下:

当limit结果为一个大于0的正整数时:

分为两种情况:

(1)当limit的值<实际分割出来的数组长度(即limit为-1时分割出来的数组长度)时,返回limit长度的数组,后几位没有分割的字符串存入数组最后一位

例如:

    @Test
    public void testSpilit() {
        String oriStr = "|1|2|3|4|||";
        String[] arr = oriStr.split("\\|",3);

结果如下:

由上面limit为-1时结果可以看到,原实际返回长度为8位。当我们limit传入3时,只返回3位长度的数组,未完成分割的,合并成一个字符串作为数组的最后一位。由上面的源码也可以看到,每进行一次分割时,都会判断当前已分割的长度是否小于limit,若不满足,则直接跳出,最后以这样的方式存入

list.add(substring(off, value.length));

off是当前未分割字符串的第一位,value.length为字符串的长度。

(2)当limit的值>=实际分割出来的数组长度,其返回结果于limit=-1时返回结果相同。

例如:

    @Test
    public void testSpilit() {
        String oriStr = "|1|2|3|4|||";
        String[] arr = oriStr.split("\\|",10);

    }

结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值