JAVA中subString以及split函数等几个函数的用法技巧

一、先说一说subString()函数

       subString函数有个陷阱,有可能导致内存泄露(当然,在JDK1.7.0-B147之前这个问题一直存在,在JDK1.7.0_15-b03版本之后这个问题已经修改过来了,至于是具体中间哪个版本修改过来的,本人没有去细看)

       在Java中,字符串是很复杂的一个问题,java有对字符串的优化,比如String POOL 对于SubString这个问题上, java也有自己的想法,比如 

         

String oldStr = "hello,clark";  
String newStr = oldStr.subString(0,4);   

对于这个写法,实际上对于oldStr是一个char[]数组[h,e,l,l,0,,,c,l,a,r,k],对于subString操作,newStr并不是自己copy oldStr的char[]数组hello自己去创建一个新的char[]数组,而是java在背后进行了String Reusing Optimization,它不会自己创建一个新的char数组,而是reuse原来的char数组。所以了,这样就不会有很多的原来的char[]数组的碎片。但是这个虽然在一般情况是好,不过也是有代价的。根据http://nflath.com/2009/07/the-dangers-of-stringsubstring/上,因为字符串不是自己新建一个char[]数组,而是引用了原来的char[]数组,这样oldStr就无法garbage collected ,因为newStr还是拥有oldStr的char[]数组的引用。这样容易引起Outof Memory 异常。解决办法是了,便是让newStr拥有自己的char[]数组,也就是自己在subString时强迫创建自己的char[]数组,这样就不会有garbage collected 的问题(reachable but unused!) 怎么办:  

   
String sub = new String( oldString.substring(0, 4) ); 
  试想:如果你要从某个大文本中直接使用subString截取某一小部分的值然后存到map中,随着程序执行的时间越来越长,那么你的程序距离内存泄漏也就不远了,所以使用subString等函数时还是new String保险起见。
二、再说一说split等几个设计到正则表达式作为参数的函数。
    第一点,split函数底层是调用的subString函数,所有首先存表时自觉注意重新new一个对象。
    第二点,如果你的split函数分割的最后有长度为0的空字符串,那么slipt函数会忽略最后的空串额
比如:
String line = "a,b,c,d,e,f,g,,";
String[] record = line.split(",");
 得到的record数组的长度是7而不是9哦,千万别傻乎乎的直接record[7],record[8]的。不防先判断判断数组的长度。
    第三点,注意特殊字符串的转义。如执行:"2|33|4".split("|")

出来的结果是:

""

2

|

3

3

|

4

奇怪吧,不过注意看一下API说明还是知道原因的.

 

java.lang.string.split 
split 方法 
将一个字符串分割为子字符串,然后将结果作为字符串数组返回。 
stringObj.split([separator,[limit]]) 
参数 
stringObj 
必选项。要被分解的 String 对象或文字。该对象不会被 split 方法修改。 
separator 
可选项。字符串或 正则表达式对象,它标识了分隔字符串时使用的是一个还是多个字符。如果忽略该选项,返回包含整个字符串的单一元素数组。 
limit 
可选项。该值用来限制返回数组中的元素个数。

说明 
split 方法的结果是一个字符串数组,在 stingObj 中每个出现 separator 的位置都要进行分解

 

 

所以正常的写法是这样的:

1、如果用“.”作为分隔的话,必须是如下写法:String.split("\\."),这样才能正确的分隔开,不能用String.split(".");
2、如果用“|”作为分隔的话,必须是如下写法:String.split("\\|"),这样才能正确的分隔开,不能用String.split("|");
“.”和“|”都是正则表达式中的特殊字符,必须得加"\\"进行转义;
3、如果在一个字符串中有多个分隔符,可以用“|”作为连字符,比如:“a=1 and b =2 or c=3”,把三个都分隔出来,可以用String.split("and|or");

     

     所以到这里正常人都应该联想到string中不止split,还有replaceAll、replaceFrist、matches等几个以正则表达式作为参数时需要将特殊字符转义处理了。

 

       

猜你喜欢

转载自zwustudy.iteye.com/blog/1848261