Java substring方法實現(xiàn)原理解析
substring實現(xiàn)原理
String是Java中一個比較基礎(chǔ)的類,每一個開發(fā)人員都會經(jīng)常接觸到。而且,String也是面試中經(jīng)常會考的知識點。String有很多方法,有些方法比較常用,有些方法不太常用。今天要介紹的subString就是一個比較常用的方法,而且圍繞subString也有很多面試題。
substring(int beginIndex, int endIndex)方法在不同版本的JDK中的實現(xiàn)是不同的。了解他們的區(qū)別可以幫助你更好的使用他。為簡單起見,后文中用substring()代表substring(int beginIndex, int endIndex)方法。
substring()的作用
substring(int beginIndex, int endIndex)方法截取字符串并返回其[beginIndex,endIndex-1]范圍內(nèi)的內(nèi)容。s
String x = "abcdef";x = x.substring(1,3);System.out.println(x);
輸出內(nèi)容:
bc
調(diào)用substring時發(fā)生了什么?
你可能知道,因為x是不可變的,當使用x.substring(1,3)對x賦值的時候,它會指向一個全新的字符串:

然而,這個圖不是完全正確的表示堆中發(fā)生的事情。因為在jdk6 和 jdk7中調(diào)用substring時發(fā)生的事情并不一樣。
JDK 6中的subString
tring是通過字符數(shù)組實現(xiàn)的。在jdk 6 中,String類包含三個成員變量:char value[], int offset,int count,他們分別用來:存儲真正的字符數(shù)組、存儲數(shù)組的第一個位置索引、存儲字符串中包含的字符個數(shù)。
當調(diào)用substring方法的時候,會創(chuàng)建一個新的string對象,但是這個string的值仍然指向堆中的同一個字符數(shù)組。這兩個對象中只有count和offset 的值是不同的。

源碼
//JDK 6
String(int offset, int count, char value[]) {
this.value = value;
this.offset = offset;
this.count = count;
}
public String substring(int beginIndex, int endIndex) {
//check boundary
return new String(offset + beginIndex, endIndex - beginIndex, value);
}
存在的問題
如果有一個很長的字符串,但是你只需要使用很短的一段,于是你使用substring進行切割,但是由于你實際上引用了整個字符串,這個很長的字符串無法被回收。往小了說,造成了存儲空間的浪費,往大了說,可能造成內(nèi)存泄漏。這個問題已經(jīng)被官方記錄在Java Bug Database里面了:

相應(yīng)的解決辦法:
s1 = s1.substring(x,y) + "";
JDK 7 中的substring
上述問題在JDK 7中得到了解決。JDK 7中,substring方法會在堆中創(chuàng)建一個新的數(shù)組。

源碼
//JDK 7
/**
* Allocates a new {@code String} that contains characters from a subarray
* of the character array argument. The {@code offset} argument is the
* index of the first character of the subarray and the {@code count}
* argument specifies the length of the subarray. The contents of the
* subarray are copied; subsequent modification of the character array does
* not affect the newly created string.
*
* @param value Array that is the source of characters
* @param offset The initial offset
* @param count The length
* @throws IndexOutOfBoundsException If the {@code offset} and {@code count} arguments index
* characters outside the bounds of the {@code value} array
*/
public String(char value[], int offset, int count) {
//check boundary
this.value = Arrays.copyOfRange(value, offset, offset + count);
}
/**
* Returns a string that is a substring of this string. The
* substring begins at the specified {@code beginIndex} and
* extends to the character at index {@code endIndex - 1}.
* Thus the length of the substring is {@code endIndex-beginIndex}.
* <p>
* Examples:
* <blockquote><pre>
* "hamburger".substring(4, 8) returns "urge"
* "smiles".substring(1, 5) returns "mile"
* </pre></blockquote>
*
* @param beginIndex the beginning index, inclusive.
* @param endIndex the ending index, exclusive.
* @return the specified substring.
* @throws IndexOutOfBoundsException if the
* {@code beginIndex} is negative, or
* {@code endIndex} is larger than the length of
* this {@code String} object, or
* {@code beginIndex} is larger than
* {@code endIndex}.
*/
public String substring(int beginIndex, int endIndex) {
//check boundary
int subLen = endIndex - beginIndex;
return ((beginIndex == 0) && (endIndex == value.length)) ?
this :
new String(value, beginIndex, subLen);
}
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于SpringBoot集成測試遠程連接Redis服務(wù)的教程詳解
這篇文章主要介紹了基于SpringBoot集成測試遠程連接的Redis服務(wù)的相關(guān)知識,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03
SpringBoot整合WebService服務(wù)的實現(xiàn)代碼
WebService是一個SOA(面向服務(wù)的編程)的架構(gòu),它是不依賴于語言,不依賴于平臺,可以實現(xiàn)不同的語言間的相互調(diào)用,通過Internet進行基于Http協(xié)議的網(wǎng)絡(luò)應(yīng)用間的交互,這篇文章主要介紹了SpringBoot整合WebService服務(wù)的實例代碼,需要的朋友可以參考下2022-02-02

