美團面試官問我一個字符 String.length()是多少我說1面試官說滾

美團面試官問我一個字符 String.length()是多少我說1面試官說滾

美團面試官問我一個字符 String.length()是多少我說1面試官說滾

美團面試官問我一個字符 String.length()是多少我說1面試官說滾

美團面試官問我一個字符 String.length()是多少我說1面試官說滾

美團面試官問我一個字符 String.length()是多少我說1面試官說滾

美團面試官問我一個字符 String.length()是多少我說1面試官說滾

美團面試官問我一個字符 String.length()是多少我說1面試官說滾

<code>public class testT {
public static void main(String [] args){
String A = "hi你是喬戈裡";
System.out.println(A.length());
}
}/<code>

以上結果輸出為7。

美團面試官問我一個字符 String.length()是多少我說1面試官說滾


美團面試官問我一個字符 String.length()是多少我說1面試官說滾

美團面試官問我一個字符 String.length()是多少我說1面試官說滾

美團面試官問我一個字符 String.length()是多少我說1面試官說滾

美團面試官問我一個字符 String.length()是多少我說1面試官說滾

美團面試官問我一個字符 String.length()是多少我說1面試官說滾


小萌邊說邊在IDEA中的win環境下選中String.length()函數,使用ctrl+B快捷鍵進入到String.length()的定義。

<code>    /**
* Returns the length of this string.
* The length is equal to the number of in the string.
*
* @return the length of the sequence of characters represented by this
* object.
*/
public int length() {

return value.length;
}/<code>

接著使用google翻譯對這段英文進行了翻譯,得到了大體意思:返回字符串的長度,這一長度等於字符串中的 Unicode 代碼單元的數目。

小萌:喬戈裡,那這又是啥意思呢?喬哥:前幾天我寫的一篇文章:[https://mp.weixin.qq.com/s/Zn-BnMd2tohHPpvMhLFYxw](https://mp.weixin.qq.com/s/Zn-BnMd2tohHPpvMhLFYxw)裡面對於Java的字符使用的編碼有介紹:

Java中 有內碼和外碼這一區分簡單來說

  • 內碼:char或String在內存裡使用的編碼方式。
  • 外碼:除了內碼都可以認為是“外碼”。(包括class文件的編碼)

而java內碼:unicode(utf-16)中使用的是utf-16.所以上面的那句話再進一步解釋就是:返回字符串的長度,這一長度等於字符串中的UTF-16的代碼單元的數目。

美團面試官問我一個字符 String.length()是多少我說1面試官說滾

美團面試官問我一個字符 String.length()是多少我說1面試官說滾


https://xiaogd.net/。UTF-X 中的數字 X 就是各自代碼單元的位數。

UTF-16 的 16 指的就是最小為 16 位一個單元,也即兩字節為一個單元,UTF-16 可以包含一個單元和兩個單元,對應即是兩個字節和四個字節。我們操作 UTF-16 時就是以它的一個單元為基本單位的。

你還記得你前幾天被面試官說菜的時候學到的Unicode知識嗎,在https://mp.weixin.qq.com/s/QjU9lSekpbaF7fugZbyzkg這裡面提到,UTF-16編碼一個字符對於U+0000-U+FFFF範圍內的字符采用2字節進行編碼,而對於字符的碼點大於U+FFFF的字符采用四字節進行編碼,前者是兩字節也就是一個代碼單元,後者一個字符是四字節也就是兩個代碼單元!

而上面我的例子中的那個字符的Unicode值就是“U+1D11E”,這個Unicode的值明顯大於U+FFFF,所以對於這個字符UTF-16需要使用四個字節進行編碼,也就是使用兩個代碼單元!

所以你才看到我的上面那個示例結果表示一個字符的String.length()長度是2!

美團面試官問我一個字符 String.length()是多少我說1面試官說滾

美團面試官問我一個字符 String.length()是多少我說1面試官說滾

美團面試官問我一個字符 String.length()是多少我說1面試官說滾

美團面試官問我一個字符 String.length()是多少我說1面試官說滾

來看個例子!

<code>public class testStringLength {
public static void main(String [] args){
String B = ""; // 這個就是那個音符字符,只不過由於當前的網頁沒支持這種編碼,所以沒顯示。
String C = "\\\\uD834\\\\uDD1E";// 這個就是音符字符的UTF-16編碼
System.out.println(C);
System.out.println(B.length());
System.out.println(B.codePointCount(0,B.length()));

}
}/<code>
美團面試官問我一個字符 String.length()是多少我說1面試官說滾

可以看到通過codePointCount()函數得知這個音樂字符是一個字符!

美團面試官問我一個字符 String.length()是多少我說1面試官說滾


幾個問題:0.codePointCount是什麼意思呢?1.之前不是說音符字符是“U+1D11E”,為什麼UTF-16是"uD834uDD1E",這倆之間如何轉換?2.前面說了UTF-16的代碼單元,UTF-32和UTF-8的代碼單元是多少呢?

美團面試官問我一個字符 String.length()是多少我說1面試官說滾

一個一個解答:

https://blog.csdn.net/u012425381/article/details/38760179

codePointCount其實就是代碼點數的意思,也就是一個字符就對應一個代碼點數。

比如剛才音符字符(沒辦法打出來),它的代碼點是U+1D11E,但它的代理單元是U+D834和U+DD1E,如果令字符串str = "u1D11E",機器識別的不是音符字符,而是一個代碼點”/u1D11“和字符”E“,所以會得到它的代碼點數是2,代碼單元數也是2。

但如果令字符str = "uD834uDD1E",那麼機器會識別它是2個代碼單元代理,但是是1個代碼點(那個音符字符),故而,length的結果是代碼單元數量2,而codePointCount()的結果是代碼點數量1.

https://mp.weixin.qq.com/s/QjU9lSekpbaF7fugZbyzkg


美團面試官問我一個字符 String.length()是多少我說1面試官說滾

上圖是對應的轉換規則:

  • 首先 U+1D11E-U+10000 = U+0D11E
  • 接著將U+0D11E轉換為二進制:0000 1101 0001 0001 1110,前10位是0000 1101 00 後10位是01 0001 1110
  • 接著套用模板:110110yyyyyyyyyy 110111xxxxxxxxxx
  • U+0D11E的二進制依次從左到右填入進模板:110110 0000 1101 00 110111 01 0001 1110
  • 然後將得到的二進制轉換為16進制:d834dd1e,也就是你看到的utf-16編碼了

第2個問題


  • 同理,UTF-32 以 32 位一個單元,它只包含這一種單元就夠了,它的一單元自然也就是四字節了。
  • UTF-8 的 8 指的就是最小為 8 位一個單元,也即一字節為一個單元,UTF-8 可以包含一個單元,二個單元,三個單元及四個單元,對應即是一,二,三及四字節。
美團面試官問我一個字符 String.length()是多少我說1面試官說滾


參考

  • 表情包出自微博@黃小B
  • https://blog.csdn.net/u012425381/article/details/38760179
  • https://xiaogd.net/
  • https://tool.oschina.net/hexconvert
  • https://baike.baidu.com/item/Unicode/750500?fr=aladdin



分享到:


相關文章: