淺談String、StringBuffer和StringBuilder之間的區(qū)別
一. String
String 類是不可變類,即一旦一個(gè)String對(duì)象被創(chuàng)建以后,包含在這個(gè)對(duì)象中的字符序列是不可改變的,直至這個(gè)對(duì)象被銷毀。
String的實(shí)例化方式
通過(guò)字面量方式實(shí)例化
String str ="abc";
通過(guò)new+構(gòu)造器的方式實(shí)例化
String str = newString("abc");區(qū)別:
- 通過(guò)字面量方式為字符串賦值時(shí),此時(shí)的字符串存儲(chǔ)在方法區(qū)的字符串常量池中;
- 通過(guò)new+構(gòu)造器方式實(shí)例化字符串時(shí),字符串對(duì)象存儲(chǔ)在堆中,但是字符串的值仍然存儲(chǔ)在方法區(qū)的常量池中。
String字符串具有不可變性,當(dāng)字符串重新賦值時(shí),不管是對(duì)字符串進(jìn)行拼接,還是調(diào)用String的replace()方法修改指定的字符或字符串,都不會(huì)在原來(lái)的內(nèi)存地址進(jìn)行修改,而是重新分配新的內(nèi)存地址進(jìn)行賦值
二. StringBuffer
StringBuffer對(duì)象代表一個(gè)字符序列可變的字符串,當(dāng)一個(gè)StringBuffer被創(chuàng)建以后,通StringBuffer提供的append()、insert()、reverse()、setCharAt()、setLength()等方法可以改變這個(gè)字符串對(duì)象的字符序列,但都不會(huì)產(chǎn)生新的對(duì)象。通過(guò)StringBuffer生成的字符串,可以調(diào)用toString()方法將其轉(zhuǎn)換為一個(gè)String對(duì)象。
StringBuffer是線程安全的
StringBuffer類中實(shí)現(xiàn)的方法,StringBuffer是如何實(shí)現(xiàn)線程安全的呢?
@Override
public synchronized int length() {
return count;
}
@Override
public synchronized int capacity() {
return value.length;
}
@Override
public synchronized void ensureCapacity(int minimumCapacity) {
super.ensureCapacity(minimumCapacity);
}
/**
* @since 1.5
*/
@Override
public synchronized void trimToSize() {
super.trimToSize();
}從源碼中可以看到,StringBuffer類中的方法都添加了synchronized關(guān)鍵字,也就是給這個(gè)方法添加了一個(gè)鎖,用來(lái)保證線程安全。
三. StringBuilder
StringBuilder類也代表可變字符串對(duì)象。實(shí)際上,StringBuilder和StringBuffer基本相似,他們的原理與操作一樣,兩個(gè)類的構(gòu)造器和方法也基本相同。
不同的是:StringBuffer是線程安全的,而StringBuilder則沒(méi)有實(shí)現(xiàn)線程安全功能,所以性能略高。
四. 總結(jié)
String、StringBuffer和StringBuilder三者的異同?
- String :不可變的字符序列;底層使用 byte[] 存儲(chǔ)。
- StringBuffer :可變的字符序列;線程安全的,效率低;底層使用 byte[] 存儲(chǔ)。
- StringBuilder :可變的字符序列;jdk5.0新增的,線程不安全的,效率高;底層使用 byte[] 存儲(chǔ)。
從代碼角度驗(yàn)證三者的效率對(duì)比
接下我們來(lái)測(cè)試下拼接10000條數(shù)據(jù)的各自所耗的時(shí)間
package com.scg.springcloudordercenter.controller;
/**
* @author gf
* @date 2023/2/21
*/
public class StringTest {
public static void main(String[] args) {
long startTime;
long endTime;
String str1 = "";
StringBuffer str2 = new StringBuffer("");
StringBuilder str3 = new StringBuilder("");
// 1.拼接str1,計(jì)算String所耗時(shí)間
startTime = System.currentTimeMillis();
for(int i= 1;i<=10000;i++){
str1 += i;
}
endTime = System.currentTimeMillis();
System.out.println("String所耗時(shí)間為:" + (endTime-startTime) + "毫秒");
// 2.拼接str2,計(jì)算StringBuffer所耗時(shí)間
startTime = System.currentTimeMillis();
for(int i= 1;i<=10000;i++){
str2.append(i);
}
endTime = System.currentTimeMillis();
System.out.println("StringBuffer所耗時(shí)間為:" + (endTime-startTime) + "毫秒");
// 3.拼接str3,計(jì)算StringBuilder所耗時(shí)間
startTime = System.currentTimeMillis();
for(int i= 1;i<=10000;i++){
str3.append(i);
}
endTime = System.currentTimeMillis();
System.out.println("StringBuilder所耗時(shí)間為:" + (endTime-startTime) + "毫秒");
}
}結(jié)果:
String所耗時(shí)間為:745毫秒
StringBuffer所耗時(shí)間為:4毫秒
StringBuilder所耗時(shí)間為:1毫秒
Process finished with exit code 0
很明顯,我們拼接一萬(wàn)次字符串操作就可以對(duì)比出三者的效率:StringBuilder>StringBuffer>String
到此這篇關(guān)于淺談String、StringBuffer和StringBuilder之間的區(qū)別的文章就介紹到這了,更多相關(guān)String、StringBuffer和StringBuilder區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IntelliJ IDEA設(shè)置顯示內(nèi)存指示器和設(shè)置內(nèi)存大小的方法
這篇文章主要介紹了IntelliJ IDEA設(shè)置顯示內(nèi)存指示器和設(shè)置內(nèi)存大小的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
Java打包之后讀取Resources下的文件失效原因及解決方法
這篇文章主要給大家介紹了Java打包之后讀取Resources下的文件失效的問(wèn)題分析和解決方法,文中通過(guò)代碼示例和圖文結(jié)合給大家講解非常詳細(xì),需要的朋友可以參考下2023-12-12
Java 線程池_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
系統(tǒng)啟動(dòng)一個(gè)新線程的成本是比較高的,因?yàn)樗婕暗脚c操作系統(tǒng)的交互。在這種情況下,使用線程池可以很好的提供性能,尤其是當(dāng)程序中需要?jiǎng)?chuàng)建大量生存期很短暫的線程時(shí),更應(yīng)該考慮使用線程池2017-05-05
基于Spring中的線程池和定時(shí)任務(wù)功能解析
下面小編就為大家?guī)?lái)一篇基于Spring中的線程池和定時(shí)任務(wù)功能解析。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09
MyBatis的各種查詢功能結(jié)果接收類型的選擇(推薦)
文章介紹了MyBatis中查詢結(jié)果的不同接收方式,包括單條數(shù)據(jù)和多條數(shù)據(jù)的處理方法,以及MyBatis的默認(rèn)類型別名,感興趣的朋友跟隨小編一起看看吧2024-11-11
詳解 Java Maximum redirects (100) exceeded
這篇文章主要介紹了詳解 Java Maximum redirects (100) exceeded的相關(guān)資料,需要的朋友可以參考下2017-05-05
自定義一個(gè)異常類模板的簡(jiǎn)單實(shí)例
下面小編就為大家?guī)?lái)一篇自定義一個(gè)異常類模板的簡(jiǎn)單實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10
MyBatis-Plus中的邏輯刪除功能及實(shí)例分析
本文將詳細(xì)講解MyBatis-Plus中的邏輯刪除特性,并結(jié)合實(shí)際案例進(jìn)行演示和說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-03-03
SpringBoot使用Druid數(shù)據(jù)源的配置方法
這篇文章主要介紹了SpringBoot使用Druid數(shù)據(jù)源的配置方法,文中代碼實(shí)例相結(jié)合的形式給大家介紹的非常詳細(xì),需要的朋友參考下吧2018-04-04

