我的个人网站:
http://riun.xyz


以下源码版本:JDK1.8

简介

Java 中 String 的 split 方法可以将字符串根据指定的间隔进行切割,例如字符串 str = “1,23,4,5” 经过 str.split(",") 切割后得到的返回值是一个字符串数组 String[] = [1, 23, 4, , 5],这种处理方式可以适配大多数场景。

问题

今天写一个读取csv文件的时候,发现一个小问题。【csv,一种文本文件格式,每行中的数据以逗号分隔,在windows平台可以使用excel打开,打开后和普通excel显示并无差别】

我处理的文件中存在这样的一行数据:

,,,,f02e843b-a328-4023-bbbd-7ce075a29bef,,,2.00422E+19,,3000,12,6,2020/10/22,1,245.05,56.34,0,301.39,245.05,56.34,0,0,301.39,0,0,0,0,,0,0,NULL,,,,,,,,,,,,,,,,,,,,

使用BufferedReader.readLine()去读取一行,然后用逗号分隔:str.split(","),最后发现拿到 的字符串数组中,前面的空串数据存在,后面的空串数据都消失了。即split切割后剩下的数据:

,,,,f02e843b-a328-4023-bbbd-7ce075a29bef,,,2.00422E+19,,3000,12,6,2020/10/22,1,245.05,56.34,0,301.39,245.05,56.34,0,0,301.39,0,0,0,0,,0,0,NULL

(后面的空串没了,到NULL结束了)

由于csv文件中,每列数据都对应的有key,例如第一列为id,第二列为name,等等,所以即使是空串也必须存在,不能丢失。

分析

在看过split源码后发现,String的split方法有两个重载方法:public String[] split(String regex)public String[] split(String regex, int limit)

而调用split(String regex)方法时,内部是直接调用的 split(regex, 0),如下图:

split(regex, 0)中,进行字符串的切割。

源码里,切割后又做了其他事情,如下:

int resultSize = list.size();
if (limit == 0) {while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {resultSize--;}
}

其中list储存结果数据。

如果我们使用split(regex)的话,会调用split(regex,0)那么就是说我们不传入limit参数,limit默认为0。所以这里会进入if语句。

进入后,就开始从后向前循环(resultSize为结果元素长度,所以是从后向前),如果是空串(length==0),就清除掉此数据(resultSize–)。

注意由于这里是 && 符号连接,所以当循环时遇到不为空串,就立即跳出while了。所以此过程清除掉的数据是结尾处的所有空串。

,,,a,bss,cas,,fq,try,,h,,,, 这个字符串使用split(",")切割后,留下的数据是,,,a,bss,cas,,fq,try,,h,在从后向前循环时碰到第一个不为空串的数据 h 就会停止,然后返回。

而我们想要让split不清除数据,拿到分隔后的原始数据时怎么办呢?看代码知道应该传入limit,让limit!=0,这样就不会进入if语句,不会执行这些清除空串数据的代码。那么limit的值应该传入什么呢?下面进行几个小实验:

# 1、
String str = ",,,a,bss,cas,,fq,try,,h,,,,";
String[] split2 = str.split(",", 1); # limit为1
System.out.println(Arrays.toString(split2));
System.out.println("长度为"+split2.length);>[,,,a,bss,cas,,fq,try,,h,,,,] # 此处是一个串
>长度为1# 2、
String str = ",,,a,bss,cas,,fq,try,,h,,,,";
String[] split2 = str.split(",", 5); # limit为5
System.out.println(Arrays.toString(split2));
System.out.println("长度为"+split2.length);>[, , , a, bss,cas,,fq,try,,h,,,,] # 此处是5个串,分别为:空串,空串,空串,a,bss,cas,,fq,try,,h,,,,
>长度为5# 3、
String str = ",,,a,bss,cas,,fq,try,,h,,,,";
String[] split2 = str.split(",", Integer.MAX_VALUE); # limit为Integer.MAX_VALUE
System.out.println(Arrays.toString(split2));
System.out.println("长度为"+split2.length);>[, , , a, bss, cas, , fq, try, , h, , , , ] # 此处将所有串都拿到了,没有清除数据。
>长度为15

当传入负数时,偶尔会运行成功,大多数情况下,会报以下错误:

结论

我们可以分析出,传入limit为正数时,split就不会帮我们清除掉它认为无用的数据,而是将limit作为结果长度的最大值进行切割。而当传入limit为0时,split会帮我们切割掉后面的空串。所以limit的含义是切割后结果的阀值(最大值),帮我们限制切割后结果的长度,limit为0时就走JAVA自己定的规则(清除结尾处的空串)。

所以当我们的使用场景需要全部数据时,要使用两个参数的split方法手动传入limit,建议limit的值为Integer.MAX_VALUE,这样可以在不知道结果长度的情况下保证结果正确。

split(regex,limit)方法的完整结构大概可分三段解释,如图:

JAVA中String的split方法相关推荐

  1. Java中String类的方法及说明

    String : 字符串类型 一.构造函数      String(byte[ ] bytes):通过byte数组构造字符串对象.      String(char[ ] value):通过char数 ...

  2. 【转载】Java中String类的方法及说明

    转载自:http://www.cnblogs.com/YSO1983/archive/2009/12/07/1618564.html String : 字符串类型 一.构造函数      String ...

  3. C库中没有itoa以及C++中string没有split方法的原因

    个人见解,欢迎讨论.这其实源于c/c++需要自己管理内存,而一个好的惯例是 自己申请的内存要自己释放掉 所以c/c++库函数一般都不会返回指针,你会说有些函数返回指针了呀,如 char *strcpy ...

  4. Java 中String的split函数简介

    在字符串处理过程中,我们经常遇到要把一个字符串转出字符数组,使用的split函数,下面就该函数进行简单说明. split 方法:将一个字符串分割为子字符串,然后将结果作为字符串数组返回. string ...

  5. Java中实现使用split方法分隔字符串

    场景 字符串为: "CAB1DM1152CJ@2097812420006@20181010,CAB1DM1152CJ@2097812420007@20181010,CAB1DM1152CJ@ ...

  6. Java中String类 compareTo()方法比较字符串详解

    中心:String 是字符串,它的比较用compareTo方法,它从第一位开始比较, 如果遇到不同的字符,则马上返回这两个字符的ascii值差值.返回值是int类型 1.当两个比较的字符串是英文且长度 ...

  7. linux+多个字符分割字符串数组中,String的split()方法可以将字符串按照特定的分隔符拆分成字符串数组...

    在java.lang包中有String.split()方法,返回是一个数组------不管按照什么拆,拆出来是一个数组 String str = "1,2,3,4,5,6"; St ...

  8. Java中String字符串截取几种方法(substring,split)

    Java中String字符串截取几种方法 substring,split 这是一个Java中的String的基础用法的演示. 下面通过代码对大家进行讲解 substring 这里用来ndexOf,la ...

  9. java substr函数_oracle 中的substr()函数的用法,以及与java中String.substring()方法的区别...

    oracle 中的substr()函数的规则是 substr( string, start_position, [ length ] ) 说明: string 是要分割的字符串 start_posit ...

最新文章

  1. 摄像头Camera标定Calibration原理Theory
  2. Lightoj1014【基础题】
  3. HugeGraph图数据库获Apache TinkerPop官方认证
  4. Rust 与 Objective-C 互操作
  5. matlab二阶系统绘制bode图,二阶系统bode图
  6. maven module 路径_解决maven项目中-Dmaven.multiModuleProjectDirectory报错问题
  7. 计算机四级c语言试题及答案,计算机等级考试试题及答案
  8. linux 中hadoop相关命令学习
  9. 上海证券综合指数昨天成功击破1000点
  10. 英特尔DSA-加速DPDK Vhost
  11. [Android]天气App 1
  12. CIC-IDS-2018数据集分析笔记
  13. TypeError错误解决方案
  14. 小程序连接低功耗蓝牙
  15. 无法在web服务器上启动调试。未能启动asp.net调试。在不调试的情况下启动项目也许能获得更多信息。
  16. POJ1190 生日蛋糕(回溯法)
  17. Tiny6410之重定位代码到SRAM+4096
  18. kaldi:计算词错率(WER)
  19. OneCoin战队——个人总结(真·终章)
  20. 企业数据仪表盘设计思路,如何设计自己的BI产品

热门文章

  1. Android Tint着色器
  2. for循环 while循环 do while循环流程图画法
  3. 图像分辨率,DPI和像素个数的关系
  4. Redis主从复制(七)
  5. java中统计英文单词数_统计单词数 Java
  6. html 模板 pug
  7. What is FAE?
  8. 拼多多新手卖家选品要注意什么?
  9. 软件版本号简易控制规范
  10. opencv摄像头闪退问题总结,解决一闪而过的问题