熟悉Java String的使用,熟悉String的各种函数,Java中各种变量类型
1.JDK 6和JDK 7中substring的原理及區(qū)別
substring(int beginIndex, int endIndex)方法截取字符串并返回其[beginIndex,endIndex-1]范圍內(nèi)的內(nèi)容。
String x = "abcdef";
x = x.substring(1,3);
System.out.println(x);
輸出內(nèi)容:
bc
調(diào)用substring()時發(fā)生了什么?
因為x是不可變的,當(dāng)使用x.substring(1,3)對x賦值的時候,它會指向一個全新的字符串:
String是通過字符數(shù)組實現(xiàn)的。在jdk 6 中,String類包含三個成員變量:char value[],?int offset,int count。他們分別用來存儲真正的字符數(shù)組,數(shù)組的第一個位置索引以及字符串中包含的字符個數(shù)。
當(dāng)調(diào)用substring方法的時候,會創(chuàng)建一個新的string對象,但是這個string的值仍然指向堆中的同一個字符數(shù)組。這兩個對象中只有count和offset 的值是不同的。
下面是證明上說觀點的Java源碼中的關(guān)鍵代碼:
//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);
}
JDK 6中的substring導(dǎo)致的問題
如果你有一個很長很長的字符串,但是當(dāng)你使用substring進(jìn)行切割的時候你只需要很短的一段。這可能導(dǎo)致性能問題,因為你需要的只是一小段字符序列,但是你卻引用了整個字符串(因為這個非常長的字符數(shù)組一直在被引用,所以無法被回收,就可能導(dǎo)致內(nèi)存泄露)。在JDK 6中,一般用以下方式來解決該問題,原理其實就是生成一個新的字符串并引用他。
x = x.substring(x, y) + ""
JDK 7 中的substring
//JDK 7
public String(char value[], int offset, int count) {
//check boundary
this.value = Arrays.copyOfRange(value, offset, offset + count);
}
?
public String substring(int beginIndex, int endIndex) {
//check boundary
int subLen = endIndex - beginIndex;
return new String(value, beginIndex, subLen);
}
2.replaceFirst、replaceAll、replace區(qū)別
String?s?=?"my.test.txt";
System.out.println(s.replace(".",?"#"));
System.out.println(s.replaceAll(".",?"#"));
System.out.println(s.replaceFirst(".",?"#"));
運行結(jié)果:
my#test#txt
###########
#y.test.txt
"."是正則表達(dá)式的元字符,匹配除換行符以外的任意字符,所以replaceAll、replaceFirst才出現(xiàn)了這樣的結(jié)果。
而replace沒有用到正則表達(dá)式,但會把所有“.”替換掉,很多人可能會誤解replace是替換單個,而replaceAll是替換全部,其實這是錯的。replace只是沒有用到正則表達(dá)式,但會替換所有匹配的字符串。
對于這種情況,反斜杠轉(zhuǎn)義一下
s.replaceFirst("\\.",?"#")
補充:String的split也是用到了正則表達(dá)式,使用的時候注意點哦!
3.String對“+”的重載
String對象是不可改變的,
查看JDK文檔,發(fā)現(xiàn)String類中每一個看似修改String的方法,實際上都創(chuàng)建了一個新的String對象,而最初的String對象則絲毫未動.
java傳遞參數(shù)的時候,傳遞的是引用的一個拷貝,調(diào)用時,都會復(fù)制一份引用,而引用所指向的對象,一直呆在某一單一物理位置,從未變動過.
重載 “+” 與 StringBuilder
public class one { public static void main(String[] args) { String a = "abc"; String b = "123" + a + "def" + 777; System.out.println(b); }}
反編譯生成的.class
javap -c one.class
編譯器自動引用java.lang.StringBuilder類,用以構(gòu)造最終的String,為每個”+”調(diào)用一次append方法,最后調(diào)用toString方法生成最終的String并保存
多個字符串拼接,如果這樣寫
String str = "";for(int i = 0; i < num; i++){ str += "a";}
在循環(huán)體內(nèi)部創(chuàng)建N個StringBuilder,造成資源浪費,影響程序性能
所以,應(yīng)該這樣寫
StringBuilder a = new StringBuilder();for(int i = 0; i < 10; i++){ a.append(i); //只有String能"+"}
4.String.valueOf和Integer.toString的區(qū)別
public String toString()
返回一個表示該 Integer 值的 String 對象。將該參數(shù)轉(zhuǎn)換為有符號的十進(jìn)制表示形式,并以字符串的形式返回它,就好像將該整數(shù)值作為參數(shù)賦予 toString(int)方法一樣。
public static String valueOf(int?i)
返回 int 參數(shù)的字符串表示形式。該表示形式恰好是單參數(shù)的 Integer.toString 方法返回的結(jié)果。
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
返回 int 參數(shù)的字符串表示形式。該表示形式恰好是單參數(shù)的 Integer.toString 方法返回的結(jié)果。
5.字符串的不可變性
一旦一個String對象在內(nèi)存中創(chuàng)建,它將是不可改變的,所有的String類中方法并不是改變String對象自己,而是重新創(chuàng)建一個新的String對象。
---------------------?
作者:yinghuananhai?
來源:CSDN?
原文:https://blog.csdn.net/YingHuaNanHai/article/details/80735505?
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!
總結(jié)
以上是生活随笔為你收集整理的熟悉Java String的使用,熟悉String的各种函数,Java中各种变量类型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常用集合类的使用
- 下一篇: TreeSet源码解析