如何选择String
字符串String是Java編程中使用概率最高的變量,也許你覺得沒有什么可講的,隨手拈來,然而字符串的處理卻尤其需要我們的關注,因為大量的字符串實例的隨意創建,給系統的效率帶來了很大的問題。
比如下面我們來做一個測試,對比String類和StringBuffer的執行效率:
●???? String執行10000次累加
long start = System.currentTimeMillis();
String str = "";
for (int i = 0; i < 10000; i++) {
??? str += "," + i;
}
long end = System.currentTimeMillis();
System.out.println(end - start);
執行的結果花費了702ms。
●???? 使用StringBuffer類來代替String類:
long start = System.currentTimeMillis();
StringBuffer str = new StringBuffer();
for (int i = 0; i < 10000; i++) {
??? str.append(",").append(i);
}
long end = System.currentTimeMillis();
System.out.println(end - start);
運行共花費了0ms。
通過對比發現StringBuffer幾乎不花費時間。這是因為,String對象的每一次累加,都會先將累加的字符串創建一個實例對象然后再累加,等于是創建了10000個實例。而StringBuffer每次都是修改的原有實例對象,只是創建了1個實例。通過學習第2章我們已經知道,創建實例需要申請內存地址、寫入數據的過程,大量的這種操作就會消耗大量的CPU計算資源。
也許你會說,StringBuffer這么高效率,那我們不再使用String類就可以了,然而實際情況是,它們在不同的情況下各有選擇的優勢。通過《高手真經 Java核心編程技術》第11.2節的講解可知,String、StringBuffer與StringBuilder三者最大的區別是:
●???? String是字符串常量
●???? StringBuffer是字符串變量(線程安全)
●???? StringBuilder是字符串變量(非線程安全)
簡要的說,String類型和StringBuffer類型的主要性能區別其實在于,String是不可變的對象,因此在每次對String類型進行改變的時候,其實都等同于生成了一個新的String對象,然后將指針指向新的String對象,所以經常改變內容的字符串最好不要用String,因為每次生成對象都會對系統性能產生影響,特別當內存中無引用對象多了以后,JVM的GC就會開始工作,那速度是一定會相當慢的。
而如果是使用StringBuffer類則結果就不一樣了,每次結果都會對StringBuffer對象本身進行操作,而不是生成新的對象,再改變對象引用。所以在一般情況下我們推薦使用StringBuffer,特別是字符串對象經常改變的情況下。而在某些特別情況下,String對象的字符串拼接其實是被JVM解釋成了StringBuffer對象的拼接,所以這些時候String對象的速度并不會比StringBuffer對象慢,而特別是以下的字符串對象生成中,String效率是遠要比StringBuffer快的:
String str = “This is only a” + “ simple” + “ test”;
StringBuffer builder = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);
你會很驚訝的發現,生成str對象的速度簡直太快了,而這個時候StringBuffer居然速度上根本一點都不占優勢。其實這是JVM的一個把戲,實際上:
String str = “This is only a” + “ simple” + “test”;
其實就是:
String str = “This is only a simple test”;
所以不需要太多的時間了。但大家這里要注意的是,如果你的字符串是來自另外的String對象的話,速度就沒那么快了,譬如:
String str2 = “This is only a”;
String str3 = “ simple”;
String str4 = “ test”;
String str1 = str2 +str3 + str4;
這時候JVM會規規矩矩的按照原來的方式去做。
為了測試這三個類的累加不同次數字符串時的效率,我們編寫一個測試類,分別按次數累加字符串:
程序11-8?TestString.java
package test.String;
?
public class TestString {
???
??? static int count = 100;//循環次數
???
// 測試String
??? public static void testString() {
??????? long start = System.nanoTime();
???? ???String str = "";
??????? for (int i = 0; i < count; i++) {
??????????? str += "," + i;
??????? }
??????? long end = System.nanoTime();
??????? System.out.println("String:" + (end - start));
??? }
???
??? // 測試StringBuffer
??? public static void testStringBuffer() {
??????? long start = System.nanoTime();
??????? StringBuffer str = new StringBuffer();
??????? for (int i = 0; i < count; i++) {
??????????? str.append(",").append(i);
??????? }
??????? long end = System.nanoTime();
??????? System.out.println("StringBuffer:" + (end - start));
??? }
???
??? // 測試StringBuilder
??? public static void testStringBuilder() {
??????? long start = System.nanoTime();
??????? StringBuilder str = new StringBuilder();
??????? for (int i = 0; i < count; i++) {
?????????? ?str.append(",").append(i);
??????? }
??????? long end = System.nanoTime();
??????? System.out.println("StringBuilder:" + (end - start));
??? }
?
??? public static void main(String[] args) {
??????? TestString.testString();
??????? TestString.testStringBuffer();
??????? TestString.testStringBuilder();
??? }
}
運行該程序執行的測試時間:
表11-2?測試結果
| 毫微秒 | String | StringBuffer | StringBuilder |
| 1次 | 69,562 | 46,934 | 8,101 |
| 10次 | 109,791 | 57,269 | 24,025 |
| 100次 | 431,619 | 172,089 | 128,228 |
| 1000次 | 8,274,236 | 876,368 | 270,985 |
| 1萬次 | 704,425,841 | 2,673,524 | 1,388,166 |
| 10萬次 | 溢出 | 20,926,961 | 11,669,361 |
| 100萬次 | 溢出 | 246,871,041 | 137,586,760 |
String在10w次循環時就溢出了,而StringBuffer在100萬次循環時間為246ms,StringBuilder的時間為137ms。顯然選擇優先級為:StringBuilder>StringBuffer>String。因此,對于這三個類的使用,我們需要按照以下情況去選擇:
●???? 如果你偶爾對簡單的字符串常量進行拼接,那么可以使用String,它足夠簡單而且輕量級;
●???? 如果你需要經常進行字符串的拼接、累加操作,請使用StringBuffer或StringBuilder;
●???? 如果是在單線程的環境中,建議使用StringBuilder,它要比StringBuffer快;如果是在多線程的環境中,建議使用StringBuffer,它是線程安全的;
因此,StringBuilder實際上是我們的首選,只有在多線程時才可以考慮使用StringBuffer,只有在字符串的拼接足夠簡單時才使用String。
?
本文出自《Java高手真經. 編程基礎卷:Java核心編程技術:Java基礎+核心庫+圖形+網絡+高級特性》一書
?
?
轉載于:https://www.cnblogs.com/haoxia/archive/2009/07/09/1519891.html
總結
以上是生活随笔為你收集整理的如何选择String的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在用visio作图形界面设计,控件对齐的
- 下一篇: 解决KMP看高清电影背景声大说话声小问题