淺談String、StringBuffer和StringBuilder之間的區(qū)別
一. String
String 類是不可變類,即一旦一個String對象被創(chuàng)建以后,包含在這個對象中的字符序列是不可改變的,直至這個對象被銷毀。
String的實例化方式
通過字面量方式實例化
String str ="abc";
通過new+構(gòu)造器的方式實例化
String str = newString("abc");區(qū)別:
- 通過字面量方式為字符串賦值時,此時的字符串存儲在方法區(qū)的字符串常量池中;
- 通過new+構(gòu)造器方式實例化字符串時,字符串對象存儲在堆中,但是字符串的值仍然存儲在方法區(qū)的常量池中。
String字符串具有不可變性,當字符串重新賦值時,不管是對字符串進行拼接,還是調(diào)用String的replace()方法修改指定的字符或字符串,都不會在原來的內(nèi)存地址進行修改,而是重新分配新的內(nèi)存地址進行賦值
二. StringBuffer
StringBuffer對象代表一個字符序列可變的字符串,當一個StringBuffer被創(chuàng)建以后,通StringBuffer提供的append()、insert()、reverse()、setCharAt()、setLength()等方法可以改變這個字符串對象的字符序列,但都不會產(chǎn)生新的對象。通過StringBuffer生成的字符串,可以調(diào)用toString()方法將其轉(zhuǎn)換為一個String對象。
StringBuffer是線程安全的
StringBuffer類中實現(xiàn)的方法,StringBuffer是如何實現(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)鍵字,也就是給這個方法添加了一個鎖,用來保證線程安全。
三. StringBuilder
StringBuilder類也代表可變字符串對象。實際上,StringBuilder和StringBuffer基本相似,他們的原理與操作一樣,兩個類的構(gòu)造器和方法也基本相同。
不同的是:StringBuffer是線程安全的,而StringBuilder則沒有實現(xiàn)線程安全功能,所以性能略高。
四. 總結(jié)
String、StringBuffer和StringBuilder三者的異同?
- String :不可變的字符序列;底層使用 byte[] 存儲。
- StringBuffer :可變的字符序列;線程安全的,效率低;底層使用 byte[] 存儲。
- StringBuilder :可變的字符序列;jdk5.0新增的,線程不安全的,效率高;底層使用 byte[] 存儲。
從代碼角度驗證三者的效率對比
接下我們來測試下拼接10000條數(shù)據(jù)的各自所耗的時間
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,計算String所耗時間
startTime = System.currentTimeMillis();
for(int i= 1;i<=10000;i++){
str1 += i;
}
endTime = System.currentTimeMillis();
System.out.println("String所耗時間為:" + (endTime-startTime) + "毫秒");
// 2.拼接str2,計算StringBuffer所耗時間
startTime = System.currentTimeMillis();
for(int i= 1;i<=10000;i++){
str2.append(i);
}
endTime = System.currentTimeMillis();
System.out.println("StringBuffer所耗時間為:" + (endTime-startTime) + "毫秒");
// 3.拼接str3,計算StringBuilder所耗時間
startTime = System.currentTimeMillis();
for(int i= 1;i<=10000;i++){
str3.append(i);
}
endTime = System.currentTimeMillis();
System.out.println("StringBuilder所耗時間為:" + (endTime-startTime) + "毫秒");
}
}結(jié)果:
String所耗時間為:745毫秒
StringBuffer所耗時間為:4毫秒
StringBuilder所耗時間為:1毫秒
Process finished with exit code 0
很明顯,我們拼接一萬次字符串操作就可以對比出三者的效率:StringBuilder>StringBuffer>String
到此這篇關(guān)于淺談String、StringBuffer和StringBuilder之間的區(qū)別的文章就介紹到這了,更多相關(guān)String、StringBuffer和StringBuilder區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springmvc接收json串,轉(zhuǎn)換為實體類List方法
今天小編就為大家分享一篇springmvc接收json串,轉(zhuǎn)換為實體類List方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08
深入解析Jdk8中Stream流的使用讓你脫離for循環(huán)
這篇文章主要介紹了Jdk8中Stream流的使用,讓你脫離for循環(huán),本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2020-02-02
Collection中的size()和isEmpty()區(qū)別說明
這篇文章主要介紹了Collection中的size()和isEmpty()區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02
Java 圖文并茂講解主方法中的String[] args參數(shù)作用
很多老鐵不清楚JAVA主方法中main()里面的的參數(shù)是什么意思,以及有什么作用,接下來給大家用最通俗易懂的話來講解,還不清楚的朋友來看看吧2022-04-04
通過反射注解批量插入數(shù)據(jù)到DB的實現(xiàn)方法
今天小編就為大家分享一篇關(guān)于通過反射注解批量插入數(shù)據(jù)到DB的實現(xiàn)方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03
springboot使用swagger-ui 2.10.5 有關(guān)版本更新帶來的問題小結(jié)
這篇文章主要介紹了springboot使用swagger-ui 2.10.5 有關(guān)版本更新帶來的問題小結(jié),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12
使用Java將海量扁平數(shù)據(jù)高效轉(zhuǎn)化為類目字典樹
在電商 ERP 與 OMS 系統(tǒng)的重構(gòu)中,構(gòu)建多級商品類目樹是一個經(jīng)典場景,本文結(jié)合實際對接海外電商平臺的業(yè)務(wù)場景,探討如何利用哈希映射將解析的時間復(fù)雜度從 O(N2) 降至 O(N),并分享了關(guān)于內(nèi)存預(yù)分配與本地緩存的進階優(yōu)化思考,需要的朋友可以參考下2026-04-04

