split函数解析

来源:互联网 发布:神思数据填充 编辑:程序博客网 时间:2024/04/30 08:29

为什么写这篇博客??

在字符串处理过程中经常会用到split函数将字符串分割成字符串数组。但是因为这个东西拿过来直接用就行很方便,但是经常出错因为不知道细节往往不好查错。于是乎今天好好读了这个源码,想把自己的理解分享一下同时有些没大看懂的地方需要高人指点。

先上源码:

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.         */        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);    }

String类的value成员为对应的底层字符数组。

Indexofint start,char ch)函数功能是从start开始找到第一个出现字符ch的位置并返回如果找不到则返回-1.

由于看到头有点疼最后一个return调用的函数没细看所以这里不做介绍。

首先介绍下split(String regex,int limit)的功能(这里只考虑满足最外层也就是第一个if条件的情况)如果limit0,此时用regex的最后一个字符把字符串分开。如下图所示:



函数调用为split(“,”,0);结果为{“”,”AA”,”DD”,”C”}四个元素 明明画了5个箭头为什么四个元素呢这是因为最后会把末尾的空串去掉。

如果limit>0的时候这时候就有点意思了。。

比如说limit=2,split(“,”,2);


是的此时空串是一部分其它的是一部分因为此时得到的数组最多只能有两个元素。有点偏离主题了好像没怎么介绍源码,源码好像大家都能看明白讲了也没意思。但是还是想分享一件个人感觉挺漂亮的东西,就是在判断字符ch不是数字字符时这里没有用ch<’0’||ch>’9’而是用的(ch-’0’)|(‘9’-ch)<0(此时不是数字字符),

这里用到的位操作只要不是数字字符两者肯定有个小于0的,当有一个为负数时做或运算肯定为负,这个小技巧还是蛮不错的。

对于这个Character.MIN_HIGH_SURROGATE 貌似是有unicode编码有关系的,与之相关的详细信息没找到,有了解这个的个人麻烦指点一下。


0 0
原创粉丝点击