这里面主要介绍一下关于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. Mysql常用语句/group by 和 having子句

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ explain: ~~~~~~~~~~~~~~~~~ ...

  2. 未能加载文件或程序集“SuperMap.Data.dll”

    重新配置的新的开发环境,使用的是原来的工程文件,编译通过,运行报错:"未能加载文件或程序集"SuperMap.Data.dll"或它的某一个依赖项.找不到指定的模块&qu ...

  3. iOS https请求 NSURLSessionDataTask

    // //  YKSHttpsRequest.m //  YKShareSdkDemo // //  Created by qingyun on 22/05/2017. //  Copyright © ...

  4. InfluxDB meta文件解析

    操作系统 : CentOS7.3.1611_x64 go语言版本:1.8.3 linux/amd64 InfluxDB版本:1.1.0 influxdb默认配置: /etc/influxdb/infl ...

  5. 每天一个linux命令:vmstat

    1.命令简介 vmstat(Virtual Memory Statistics 虚拟内存统计) 命令用来显示Linux系统虚拟内存状态,也可以报告关于进程.内存.I/O等系统整体运行状态. 2.用法 ...

  6. 【PMP】事业环境因素和组织过程资产

    事业环境因素(EEFs) 事业环境因素(EEFs):是指组织不能控制的,将对项目产生影响.限制或指令作用的各种条件. ①组织内部的事业环境因素: 组织文化.结构和治理 设施和资源的地理分布 基础设施 ...

  7. Rabbit五种消息队列学习(二) – 简单队列

    队列结构图 P:消息的生产者 C:消息的消费者 红色:队列 生产者将消息发送到队列,消费者从队列中获取消息. 测试 1.连接MQ public static Connection getConnect ...

  8. MySQL技术内幕读书笔记(六)——索引与算法之全文索引

    全文索引 概述 ​ 通过索引字段的前缀进行查找,B+树索引是支持的,利用B+树索引就可以进行快速查询. SELECT * FROM blog WHERE content like 'xxx%'; ​ ...

  9. SELECT INTO和INSERT INTO SELECT的区别 类似aaa?a=1&b=2&c=3&d=4,如何将问号以后的数据变为键值对 C# 获取一定区间的随即数 0、1两个值除随机数以外的取值方法(0、1两个值被取值的概率相等) C# MD5 加密,解密 C#中DataTable删除多条数据

    SELECT INTO和INSERT INTO SELECT的区别   数据库中的数据复制备份 SELECT INTO: 形式: SELECT value1,value2,value3 INTO Ta ...

  10. Centos7.4修改主机名HostName颜色及格式

    一.打开 .bashrc文件 1.位置:~(cd ~)目录下 2.cat .bashrc 原文件内容如下: # .bashrc # User specific aliases and function ...