為什么 Java 8 中不需要 StringBuilder 拼接字符串
在Java開發(fā)者中,字符串的拼接占用資源高往往是熱議的話題.
讓我們深入討論一下為什么會(huì)占用高資源。
在Java中,字符串對(duì)象是不可變的,意思是它一旦創(chuàng)建,你就無(wú)法再改變它。所以在我們拼接字符串的時(shí)候,創(chuàng)建了一個(gè)新的字符串,舊的被垃圾回收器所標(biāo)記。

如果我們處理上百萬(wàn)的字符串,然后,我們就會(huì)生成百萬(wàn)的額外字符串被垃圾回收器處理。
虛擬機(jī)底層在拼接字符串時(shí)執(zhí)行了眾多操作。拼接字符串最直接的點(diǎn)操作(dot operator)就是String#concat(String)操作。
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
public static char[] copyOf(char[] original, int newLength) {
char[] copy = new char[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
void getChars(char dst[], int dstBegin) {
System.arraycopy(value, 0, dst, dstBegin, value.length);
}
你可以看到一個(gè)字符數(shù)組被創(chuàng)建,長(zhǎng)度則是已有字符和拼接的字符長(zhǎng)度之和。然后,它們的值復(fù)制到新的字符數(shù)組中。最后,用這個(gè)字符數(shù)組創(chuàng)建一個(gè)String對(duì)象并返回。
所以這些操作繁多,如果你計(jì)算一下,會(huì)發(fā)現(xiàn)是O(n^2)的復(fù)雜度。
為了解決這個(gè)問(wèn)題,我們使用StringBuilder類。它就像可變的String類。拼接方法幫助我們避免不必要的復(fù)制。它擁有O(n)的復(fù)雜度,遠(yuǎn)遠(yuǎn)優(yōu)于O(n^2)。
然而Java 8默認(rèn)使用StringBuilder拼接字符串。
Java 8的文檔說(shuō)明:
為了提高字字符串拼接的性能,Java編譯器可以使用StringBuffer類或類似技術(shù),在使用求值表達(dá)式時(shí),減少中間String對(duì)象的創(chuàng)建。
Java編譯器處理這種情況:
public class StringConcatenateDemo {
public static void main(String[] args) {
String str = "Hello ";
str += "world";
}
}
上面的代碼會(huì)被編譯成如下字節(jié)碼:
public class StringConcatenateDemo {
public StringConcatenateDemo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String Hello
2: astore_1
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: aload_1
11: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: ldc #6 // String world
16: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: astore_1
23: return
}
你可以在這些字節(jié)碼中看到,使用了StringBuilder。所以我們?cè)贘ava 8中不再需要使用StringBuilder類。
英文原文:We Don't Need StringBuilder for Concatenation Anymore
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot+SseEmitter和Vue3+EventSource實(shí)現(xiàn)實(shí)時(shí)數(shù)據(jù)推送
本文主要介紹了SpringBoot+SseEmitter和Vue3+EventSource實(shí)現(xiàn)實(shí)時(shí)數(shù)據(jù)推送,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-03-03
springboot?集成identityserver4身份驗(yàn)證的過(guò)程解析
這篇文章主要介紹了springboot?集成identityserver4身份驗(yàn)證的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01
Request的包裝類HttpServletRequestWrapper的使用說(shuō)明
這篇文章主要介紹了Request的包裝類HttpServletRequestWrapper的使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
RabbitMQ中的prefetch_count參數(shù)詳解
這篇文章主要介紹了RabbitMQ中的prefetch_count參數(shù)用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
Spring的@PreAuthorize注解自定義權(quán)限校驗(yàn)詳解
這篇文章主要介紹了Spring的@PreAuthorize注解自定義權(quán)限校驗(yàn)詳解,由于項(xiàng)目中,需要對(duì)外開放接口,要求做請(qǐng)求頭校驗(yàn),不做其他權(quán)限控制,所以準(zhǔn)備對(duì)開放的接口全部放行,不做登錄校驗(yàn),需要的朋友可以參考下2023-11-11
淺析java程序中hibernate的應(yīng)用總結(jié)
hibernate可以理解為是一個(gè)中間件它負(fù)責(zé)把java程序的sql語(yǔ)句接收過(guò)來(lái)發(fā)送到數(shù)據(jù)庫(kù),而數(shù)據(jù)庫(kù)返回來(lái)的信息hibernate接收之后直接生成一個(gè)對(duì)象傳給java2013-07-07
java使用listIterator逆序arraylist示例分享
對(duì)于列表而言,除了Iterator,還提供了一個(gè)功能更加強(qiáng)大的ListIterator。它可以實(shí)現(xiàn)逆序遍歷列表中的元素。本示例將使用其逆序遍歷ArrayList2014-02-02
使用Spring boot + jQuery上傳文件(kotlin)功能實(shí)例詳解
本文通過(guò)實(shí)例代碼給大家介紹了使用Spring boot + jQuery上傳文件(kotlin) 功能,需要的朋友可以參考下2017-07-07
Java參數(shù)傳遞及值傳遞實(shí)現(xiàn)原理詳解
這篇文章主要介紹了Java參數(shù)傳遞及值傳遞實(shí)現(xiàn)原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08

