欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Java 字符串拼接效率分析及最佳實(shí)踐
  1. java連接字符串有多種方式,比如+操作符, StringBuilder.append 方法,這些方法各有什么優(yōu)劣(可以適當說(shuō)明各種方式的實(shí)現細節)?

  2. 按照高效的原則,那么java中字符串連接的最佳實(shí)踐是什么?

  3. 有關(guān)字符串處理,都有哪些其他的最佳實(shí)踐?

廢話(huà)不多說(shuō),直接開(kāi)始, 環(huán)境如下:

JDK版本: 1.8.0_65

CPU: i7 4790`

內存: 16G

直接使用 + 拼接

看下面的代碼:

在上面的代碼中,我們使用加號來(lái)連接四個(gè)字符串,這種字符串拼接的方式優(yōu)點(diǎn)很明顯: 代碼簡(jiǎn)單直觀(guān),但是對比 StringBuilderStringBuffer大部分情況下 比后者都低,這里說(shuō)是 大部分情況下 ,我們用javap工具對上面代碼生成的字節碼進(jìn)行反編譯看看在編譯器對這段代碼做了什么。

從反編譯的結果來(lái)看,實(shí)際上對字符串使用 + 操作符進(jìn)行拼接,編譯器會(huì )在編譯階段把代碼優(yōu)化成使用 StringBuilder 類(lèi),并調用 append 方法進(jìn)行字符串拼接,最后調用 toString 方法,這樣看來(lái)是否可以認為在一般情況下 其實(shí)直接使用+,反正編譯器也會(huì )幫我優(yōu)化為使用StringBuilder ?

StringBuilder 源碼分析

答案自然是 不可以 的,原因就在于 StringBuilder 這個(gè)類(lèi)它內部做了些什么時(shí)。

我們看一看 StringBuilder 類(lèi)的構造器

StringBuilder 提供了4個(gè)默認的構造器, 除了無(wú)參構造函數外,還提供了另外3個(gè)重載版本,而內部都調用父類(lèi)的 super(int capacity) 構造方法,它的父類(lèi)是 AbstractStringBuilder ,構造方法如下:

可以看到實(shí)際上StringBuilder內部使用的是 char數組 來(lái)存儲數據(String、StringBuffer也是),這里 capacity 的值指定了數組的大小。結合 StringBuilder 的無(wú)參構造函數,可以知道默認的大小是 16 個(gè)字符。

也就是說(shuō)如果待拼接的字符串總長(cháng)度不小于16的字符的話(huà),那么其實(shí)直接拼接和我們手動(dòng)寫(xiě)StringBuilder區別不大,但是我們自己構造StringBuilder類(lèi)可以指定數組的大小,避免分配過(guò)多的內存。

現在我們再看看 StringBuilder.append 方法內部做了什么事:

直接調用的父類(lèi)的 append方法

在這個(gè)方法內部調用了 ensureCapacityInternal 方法,當拼接后的字符串總大小大于內部數組 value 的大小時(shí),就必須先擴容才能拼接,擴容的代碼如下:

StringBuilder 在擴容時(shí)把容量增大到 當前容量的兩倍+2 ,這是很可怕的,如果在構造的時(shí)候沒(méi)有指定容量,那么很有可能在擴容之后占用了浪費大量的內存空間。其次擴容后還調用了 Arrays.copyOf 方法,這個(gè)方法把擴容前的數據復制到擴容后的空間內,這樣做的原因是: StringBuilder 內部使用 char數組 存放數據,java的數組是不可擴容的,所以只能重新申請一片內存空間,并把已有的數據復制到新的空間去,這里它最終調用了 System.arraycopy 方法來(lái)復制,這是一個(gè)native方法,底層直接操作內存,所以比我們用循環(huán)來(lái)復制要塊的多,即便如此,大量申請內存空間和復制數據帶來(lái)的影響也不可忽視。

使用 + 拼接和使用 StringBuilder 比較

上面這段代碼經(jīng)過(guò)優(yōu)化后相當于:

一眼就能看出 創(chuàng )建了太多的StringBuilder對象 ,而且在每次循環(huán)過(guò)后str越來(lái)越大,導致每次申請的內存空間越來(lái)越大,并且當str長(cháng)度大于16時(shí),每次都要擴容兩次!而實(shí)際上 toString 方法在創(chuàng )建 String 對象時(shí),調用了 Arrays.copyOfRange方法來(lái)復制數據,此時(shí)相當于每執行一次,擴容了兩次,復制了3次數據,這樣的代價(jià)是相當高的。

這段代碼的執行時(shí)間在我的機器上都是0ms(小于1ms)和1ms,而上面那段代碼則大約在380ms!效率的差距相當明顯。

同樣是上面的代碼,將循環(huán)次數調整為 1000000 時(shí),在我的機器上,有指定 capacity 時(shí)耗時(shí)大約20ms,沒(méi)有指定 capacity 時(shí)耗時(shí)大約29ms,這個(gè)差距雖然和直接使用 + 操作符有了很大的提升(且循環(huán)次數增大了100倍),但是它依舊會(huì )觸發(fā)多次擴容和復制。

將上面的代碼改成使用 StringBuffer ,在我的機器上,耗時(shí)大約為33ms,這是因為 StringBuffer 在大部分方法上都加上了 synchronized 關(guān)鍵字來(lái)保證線(xiàn)程安全,執行效率有一定程度上的降低。

使用 String.concat 拼接

現在再看這段代碼:

這段代碼使用了 String.concat 方法,在我的機器上,執行時(shí)間大約為130ms,雖然直接相加要好的多,但是比起使用 StringBuilder 還要太多了,似乎沒(méi)什么用。其實(shí)并不是,在很多時(shí)候,我們只需要連接兩個(gè)字符串,而不是多個(gè)字符串的拼接,這個(gè)時(shí)候使用 String.concat 方法比 StringBuilder 要簡(jiǎn)潔且效率要高。

上面這段是 String.concat 的源碼,在這個(gè)方法中,調用了一次Arrays.copyOf,并且指定了 len + otherLen ,相當于分配了一次內存空間,并分別從str1和str2各復制一次數據。而如果使用 StringBuilder 并指定 capacity ,相當于分配一次內存空間,并分別從str1和str2各復制一次數據,最后因為調用了 toString 方法,又復制了一次數據。

結論

現在根據上面的分析和測試可以知道:

  1. Java中字符串拼接不要直接使用 + 拼接。

  2. 使用StringBuilder或者StringBuffer時(shí),盡可能準確地估算capacity,并在構造時(shí)指定,避免內存浪費和頻繁的擴容及復制。

  3. 在沒(méi)有線(xiàn)程安全問(wèn)題時(shí)使用 StringBuilder , 否則使用 StringBuffer 。

  4. 兩個(gè)字符串拼接直接調用 String.concat 性能最好。

關(guān)于 String 的其他最佳實(shí)踐:

  1. equals 時(shí)總是把能確定不為空的變量寫(xiě)在左邊,如使用 ''.equals(str) 判斷空串,避免空指針異常。

  2. 第二點(diǎn)是用來(lái)排擠第一點(diǎn)的.. 使用 str != null && str.length() != 0 來(lái)判斷空串,效率比第一點(diǎn)高。

  3. 在需要把其他對象轉換為字符串對象時(shí),使用 String.valueOf(obj) 而不是直接調用 obj.toString() 方法,因為前者已經(jīng)對空值進(jìn)行檢測了,不會(huì )拋出空指針異常。

  4. 使用 String.format() 方法對字符串進(jìn)行格式化輸出。

  5. 在JDK 7及以上版本,可以在 switch 結構中使用字符串了,所以對于較多的比較,使用 switch 代替 if-else 。

  6. 我暫時(shí)想的起來(lái)的就這么幾個(gè)了.. 請大家幫忙補充補充...

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
面試官:說(shuō)說(shuō)這段代碼存在什么問(wèn)題?
String類(lèi)相關(guān)面試題很難?不要方,本文將讓你徹底明白!
Java高質(zhì)量代碼之 — 字符串
java提高篇(十四)-----字符串
Java筆試題分類(lèi)總結
面經(jīng)手冊 · 第11篇《StringBuilder 比 String 快?空嘴白牙的,證據呢!》
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久