博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从源码分析:Java中的split()方法
阅读量:4039 次
发布时间:2019-05-24

本文共 3713 字,大约阅读时间需要 12 分钟。

从字符串中出现多次空格时使用’split()'说起

我们一般在使用java中的字符串类String中的split()时,比如希望用空格将其隔开时,往往会默认每次只有一个空格出现,那么若出现多个空格,会发生什么呢?

这里,我们可以做一个简单的测试:

public class JavaSplitTest {
public static void main(String[] args) {
String s = "a b"; String[] strs = s.split(" "); System.out.println(strs.length); }}

输出:

4

在上面的这段测试代码中,在单词a与b之间,有3个空格,如果我们认为这些会被当作一个空格看待的话,输出的数组的长度应该是2才对,那么,这个字符串数组strs中,究竟有哪些元素呢?

我们可以在程序上设置断点来通过Debug查看:

在这里插入图片描述

在这里插入图片描述
可以看到,数组strs中除了我们期望存在的a与b之外,其之间还有着两个空元素。

所以,我们猜测,是每两个空格之间的元素都会被储存下来么?

为了印证我们的猜测,可以将a与b之间的空格的数量扩大为10个,那么,此时,结果的数组的长度应该变为11。

接下来,我们通过实验来看一下结果:

public class JavaSplitTest {
public static void main(String[] args) {
String s = "a b"; String[] strs = s.split(" "); System.out.println(strs.length); }}

结果:

11

这样的结果印证了我们前面的猜测。如果只是使用的话,那么看到这里应该就可以帮助读者在接下来的编程中避免一些失误了。

但是,如果想要详细研究一下的话,我们可以从源码来进行分析。

源码分析

我们接下来就可以来看String中的split()的源码了:

首先看一下我们刚才用的方法split(String regex):

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

指向了另一个多参数的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
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);}

这里代码可能比较长,我们可以看一下其中的这一段:

int off = 0;int next = 0;boolean limited = limit > 0;ArrayList
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; }}

也就是最开始紧跟着最开始的很长的一个判断语句后面的一段,其中的ch的值来自于判断语句中的ch = regex.charAt(0)(只要split的参数中不包含".$|()[{^?*+\",那么ch变量就是在这里赋值)。

其中,off为要找的子字符串的起始位置,next为其结束位置,即分隔符所在的位置。list用来储存子字符串。

而子字符串向list中添加的方式为list.add(substring(off, next));,也就是说,每次找到一个分隔符的时候,就会向list中添加一次,而substring函数中,若起始位置与终止位置为相邻的话,只会添加一个"",也就是我们在开始的实验中所看到的空的元素了。

转载地址:http://dmsdi.baihongyu.com/

你可能感兴趣的文章
使用mkimage制作uboot脚本
查看>>
全球海底光缆分布图-Submarine Cable Map
查看>>
很有用的图像数据转换工具
查看>>
uboot内存布局
查看>>
uboot移植-内存分布
查看>>
ubuntu下如何把用户的语言环境变量改为中文
查看>>
Ubuntu Server 16.04修改IP、DNS、hosts
查看>>
几个可以替代百度的搜索引擎
查看>>
BT.656标准简介
查看>>
BT.601与BT.656
查看>>
标准BT.656并行数据结构
查看>>
A Brief Introduction to Digital Video
查看>>
数字视频接口
查看>>
my.cnf 自动生成脚本
查看>>
如何通过instant client 来连接数据库以及使用exp/imp?
查看>>
flask +python+vue 监控软件(一)
查看>>
flask +python+vue 监控软件(二)
查看>>
go AES加密解密
查看>>
python AES加密解密,key的长度不受限制
查看>>
oracle 查询sequnce# 在哪个归档备份集下面
查看>>