这里面主要介绍一下关于String类中的split方法的使用以及原理。

split函数的说明

split函数java docs的说明:

When there is a positive-width match at the beginning of this string then an empty leading substring is included at the beginning of the resulting array.A zero-width match at the beginning however never produces such empty leading substring.

The limit parameter controls the number of times the pattern is applied and therefore affects the length of the resulting array. If the limit n is greater than zero then the pattern will be applied at most n -  times, the array's length will be no greater than n, and the array's last entry will contain all input beyond the last matched delimiter. If n is non-positive then the pattern will be applied as many times as possible and the array can have any length. If n is zero then the pattern will be applied as many times as possible, the array can have any length, and trailing empty strings will be discarded.

split函数的工作原理大概可以分为以下的几步:

、遍历查找到regex,把regex前面到上一次的位置中间部分添加到list。这是split函数的核心部分
、如果没有找到,则返回自身的一维数组
、是否添加剩余的内容到list中
、是否去除list里面的空字符串
、从上面的list里面返回成数组

对于split函数limit的值可能会出现以下的几种情况:

、Limit < , e.g. limit = -
、limit = ,不传默认是0
、Limit > ,e.g. limit =
、limit > size,e.g. limit =

split函数的原理

我们通过以下的例子来分析一下split函数的原理。

public void test() {
String string = "linux---abc-linux-";
splitStringWithLimit(string, -);
splitStringWithLimit(string, );
splitStringWithLimit(string, );
splitStringWithLimit(string, );
} public void splitStringWithLimit(String string, int limit) {
String[] arrays = string.split("-", limit);
String result = MessageFormat.format("arrays={0}, length={1}", Arrays.toString(arrays), arrays.length);
System.out.println(result);
} // arrays=[linux, , , abc, linux, ], length=6
// arrays=[linux, , , abc, linux], length=5
// arrays=[linux, , -abc-linux-], length=3
// arrays=[linux, , , abc, linux, ], length=6

一、关于第一步的操作,分为两个分支。

1、如果regex是正则表达式的元字符:".$|()[{^?*+\\”,或者regex是以\开头,以不是0-9, a-z, A-Z结尾的双字符。
    
if (((regex.value.length ==  &&
".$|()[{^?*+\\".indexOf(ch = regex.charAt()) == -) ||
(regex.length() == &&
regex.charAt() == '\\' &&
(((ch = regex.charAt())-'')|(''-ch)) < &&
((ch-'a')|('z'-ch)) < &&
((ch-'A')|('Z'-ch)) < )) &&
(ch < Character.MIN_HIGH_SURROGATE ||
ch > Character.MAX_LOW_SURROGATE))
使用index函数查找regex的位置,维护两个下标变量。off表示上一次查找的位置(第一次off是0),next是本次查找的位置。每次查找之后把off到next中间的内容添加到list中。最后更新off的值为next+1。以供下一次的查找。
{
int off = ;
int next = ;
boolean limited = limit > ;
ArrayList<String> list = new ArrayList<>();
while ((next = indexOf(ch, off)) != -) {
if (!limited || list.size() < limit - ) {
list.add(substring(off, next));
off = next + ;
} 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 == )
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 == ) {
while (resultSize > && list.get(resultSize - ).length() == ) {
resultSize--;
}
}
String[] result = new String[resultSize];
return list.subList(, resultSize).toArray(result);
}
2、如果regex不满足上面的判断,比如说是长度大于2的字符。
return Pattern.compile(regex).split(this, limit);

使用正则表达式的mather函数,查找到regex的位置。维护着index变量,相当于上述的off。而matcher查找到的m.start()则相当于上述的next。每次查找之后把index到m.start()中间的内容添加到list中。最后更新off的值为m.end()。以供下一次的查找。

 public String[] split(CharSequence input, int limit) {
int index = ;
boolean matchLimited = limit > ;
ArrayList<String> matchList = new ArrayList<>();
Matcher m = matcher(input); // Add segments before each match found
while(m.find()) {
if (!matchLimited || matchList.size() < limit - ) {
if (index == && index == m.start() && m.start() == m.end()) {
// no empty leading substring included for zero-width match
// at the beginning of the input char sequence.
continue;
}
String match = input.subSequence(index, m.start()).toString();
matchList.add(match);
index = m.end();
} else if (matchList.size() == limit - ) { // last one
String match = input.subSequence(index,
input.length()).toString();
matchList.add(match);
index = m.end();
}
} // If no match was found, return this
if (index == )
return new String[] {input.toString()}; // Add remaining segment
if (!matchLimited || matchList.size() < limit)
matchList.add(input.subSequence(index, input.length()).toString()); // Construct result
int resultSize = matchList.size();
if (limit == )
while (resultSize > && matchList.get(resultSize-).equals(""))
resultSize--;
String[] result = new String[resultSize];
return matchList.subList(, resultSize).toArray(result);
}

二、关于第二步:

如果off为0,也就是没有找到regex。直接返回自身的一维数组。 
 

三、关于第三步:

如果limit <= 0或者list的长度还没有达到我们设置的Limit数值。那么就把剩下的内容(最后的一个regex位置到末尾)添加到list中。 
 

四、关于第四步

这里针对的是limit等于0的处理。如果limit=0,那么会把会从后向前遍历list的内容。去除空的字符串(中间出现的空字符串不会移除) 。
 

五、关于第五步

调用List里面的toArray方法,返回数组。 
  

友情链接

java基础---->String中的split方法的原理的更多相关文章

  1. java基础---->String中replace和replaceAll方法

    这里面我们分析一下replace与replaceAll方法的差异以及原理. replace各个方法的定义 一.replaceFirst方法 public String replaceFirst(Str ...

  2. java.lang.String中的replace方法到底替换了一个还是全部替换了。

    你没有看错我说的就是那个最常用的java.lang.String,String可以说在Java中使用量最广泛的类了. 但是我却发现我弄错了他的一个API(也可以说是两个API),这个API是关于字符串 ...

  3. Java的String中的subString()方法

    方法如下: public String substring(int beginIndex, int endIndex) 第一个int为开始的索引,对应String数字中的开始位置, 第二个是截止的索引 ...

  4. java.lang.String中的trim()方法的详细说明(转)

    String.Trim()方法到底为我们做了什么,仅仅是去除字符串两端的空格吗? 一直以为Trim()方法就是把字符串两端的空格字符给删去,其实我错了,而且错的比较离谱. 首先我直接反编译String ...

  5. PL/SQL实现JAVA中的split()方法的小例子

    众所周知,java中为String类提供了split()字符串分割的方法,所以很容易将字符串以指定的符号分割为一个字符串数组.但是在pl/sql中并没有提供像java中的split()方法,所以要想在 ...

  6. Java基础String的方法

    Java基础String的方法 字符串类型写法格式如下: 格式一: String 变量名称; 变量名称=赋值(自定义或传入的变量值); 格式二: String 变量名称=赋值(自定义或传入的变量值); ...

  7. java.lang.String 类的所有方法

    java.lang.String 类的所有方法 方法摘要 char charAt(int index) 返回指定索引处的 char 值. int codePointAt(int index) 返回指定 ...

  8. 2017.10.28 针对Java Web应用中错误异常处理方法的运用

    针对Java Web应用中错误异常处理方法的运用 在javaweb中其异常都需要对Checked Exception之下的Exception进行继承,并且有选择地对发生的错误和异常进行处理.Java同 ...

  9. Java基础关于Map(字典)的方法使用

    Java基础关于Map(字典)的方法使用 java中一般用map与hashmap来创建一个key-value对象 使用前提是要导入方法包: import java.util.HashMap: impo ...

随机推荐

  1. python基础-requests模块、异常处理、Django部署、内置函数、网络编程

     网络编程 urllib的request模块可以非常方便地抓取URL内容,也就是发送一个GET请求到指定的页面,然后返回HTTP的响应. 校验返回值,进行接口测试: 编码:把一个Python对象编码转 ...

  2. js小题目(持续更新)

    总是感觉之前做过的问题很久没碰的话就会忘掉,于是打算专门开一个记录小题目的随笔当题典用. 目录 五种主要数据类型进行值复制 数组去重 数组去重并计数 实现clone()方法,对五种主要数据类型进行值复 ...

  3. win10下搭建storm环境

    原文:https://blog.csdn.net/lu_wei_wei/article/details/80843365 1.下载storm; http://mirror.bit.edu.cn/apa ...

  4. Python多进程池 multiprocessing Pool

    1. 背景 由于需要写python程序, 定时.大量发送htttp请求,并对结果进行处理. 参考其他代码有进程池,记录一下. 2. 多进程 vs 多线程 c++程序中,单个模块通常是单进程,会启动几十 ...

  5. HTML语言字符编码

    ! ! — 惊叹号Exclamation mark ” " " 双引号Quotation mark # # — 数字标志Number sign $ $ — 美元标志Dollar s ...

  6. VS2015 ionic 开发环境配置纪要

    1)第一次安装Tools for Apache Cordova不成功,到Options检查依赖项,缺少Node等,重新下载了32为的nodeJs安装.然后运行VS安装程序,卸载Tools for Ap ...

  7. 说说Python编码规范

    前言 已有近两个月没有发表过文章了,前段时间外甥和女儿过来这边渡暑假,平常晚上和周末时间都陪着她们了,趁这个周末有空,再抽空再把这块拾起来.         这么久没写了,再次拿起键盘,想想,发表些什 ...

  8. 面试汇总——说一下CSS盒模型

    本文是面试汇总分支——说一下CSS盒模型. 基本概念:W3C标准盒模型和IE盒模型 CSS如何设置这两种模型 JS如何获取盒模型对应的宽和高 根据盒模型解释边距重叠 BFC(边距重叠解决方案) 一. ...

  9. Atitit 项目版本管理gitflow 与 Forking的对比与使用

    Atitit 项目版本管理gitflow 与 Forking的对比与使用 1.1. 版本管理的历史 csv>>svn >git 1 1.2. gitflow的核心是分版本管理,for ...

  10. mac关闭占用某个端口的进程

    在启动项目的时候有时候会提示端口被占用,但是怎么都找不到那个关闭进程的地方,可以直接通过命令行关闭这个进程: 比如要关闭:8000端口的进程: 1. 查找端口进程: lsof -i: 会把所有的占用8 ...