计算string长度 java_夯实基础:掌握从Java 9+开始的String的空间优化
作者:稀土掘金
原文:https://juejin.im/post/5aff7f10518825426e0233ea
據(jù)我所知 Java 開發(fā)人員幾乎任何時(shí)候都會(huì)想到 String,字符串確實(shí)已經(jīng)成為最常用的類了,而且是大量使用。我們都知道,String 其實(shí)是封裝了字符,里面必須由字符或字節(jié)數(shù)組來(lái)存放,從 Java9 開始 Java 語(yǔ)言開發(fā)者對(duì) String 做了一些空間的優(yōu)化。
從char到byte
JDK9 之前的庫(kù)的 String 類的實(shí)現(xiàn)使用了 char 數(shù)組來(lái)存放字符串,char 占用16位,即兩字節(jié)。
private final char value[];這種情況下,如果我們要存儲(chǔ)字符 A ,則為 0x00 0x41 ,此時(shí)前面的一個(gè)字節(jié)空間浪費(fèi)了。但如果保存中文字符則不存在浪費(fèi)的情況,也就是說(shuō)如果保存 ISO-8859-1 編碼內(nèi)的字符則浪費(fèi),之外的字符則不會(huì)浪費(fèi)。
而 JDK9 后 String 類的實(shí)現(xiàn)使用了 byte 數(shù)組存放字符串,每個(gè) byte 占用8位,即1字節(jié)。
private final byte[] value編碼
String 支持多種編碼,但如果不指定編碼的話,它可能使用兩種編碼,分別為 LATIN1 和 UTF16。LATIN1 可能比較陌生,其實(shí)就是 ISO-8859-1 編碼,屬于單字節(jié)編碼。而 UTF16 為雙字節(jié)編碼,它使用1個(gè)或2個(gè)16位長(zhǎng)的空間存儲(chǔ)。
壓縮空間
壓縮的字符對(duì)象主要是在 ISO-8859-1 編碼內(nèi)的字符,比如英語(yǔ)字母數(shù)字還有其他常見(jiàn)符號(hào)。為了更好理解我們看下圖,假如我們有一個(gè)“what”字符串,那么如果在 Java9 之前,它的存儲(chǔ)是按如下隊(duì)列排列的,可以看到每個(gè)字符都需要16位來(lái)存儲(chǔ),而高字節(jié)位都為0,這個(gè)其實(shí)就是浪費(fèi)了。
而在 Java9 后,它的存儲(chǔ)的排列則很緊湊了,如下圖,只需四個(gè)字節(jié)即可。
但如果是“哈a”,則布局為下圖,所以如果字符串中的字符一旦包含了不在 ISO-8859-1 編碼內(nèi)的字符,則同樣還是統(tǒng)一使用16位長(zhǎng)度來(lái)保存。
Java9 的 String 默認(rèn)是使用了上述緊湊的空間布局的,看如下代碼,默認(rèn)將 COMPACT_STRINGS 設(shè)置為 true。而如果要取消緊湊的布局可以通過(guò)配置 VM 參數(shù) -XX:-CompactStrings 實(shí)現(xiàn)。
static final boolean COMPACT_STRINGS;static { COMPACT_STRINGS = true;}字符串長(zhǎng)度
因?yàn)楦淖兞?String 的實(shí)現(xiàn),使用了 UTF-16 或 LATIN-1 編碼,所以內(nèi)部需要一個(gè)標(biāo)識(shí) coder 來(lái)表示使用了哪種編碼,LATIN1 值為0,UTF16 值為1。
private final byte coder;static final byte LATIN1 = 0;static final byte UTF16 = 1;而字符串的長(zhǎng)度也與編碼相關(guān),計(jì)算時(shí)通過(guò)右移來(lái)實(shí)現(xiàn)。如果是 LATIN-1 編碼,則右移0位,數(shù)組長(zhǎng)度即為字符串長(zhǎng)度。而如果是 UTF16 編碼,則右移1位,數(shù)組長(zhǎng)度的二分之一為字符串長(zhǎng)度。
public int length() { return value.length >> coder();}總結(jié)
字符串對(duì)象是 Java 中大量使用的對(duì)象,而且我們會(huì)輕易大量使用它而從不考慮它的代價(jià),所以對(duì)其的空間優(yōu)化是有必要的,Java9 開始對(duì) 這能幫助我們減少字符串在堆中占用的空間,而且還能減輕GC壓力。同時(shí)也能看到該空間優(yōu)化對(duì)中文來(lái)說(shuō)意義不大。
總結(jié)
以上是生活随笔為你收集整理的计算string长度 java_夯实基础:掌握从Java 9+开始的String的空间优化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java list 转 map_高并发下
- 下一篇: 《文明5》初步攻略