本文首发于程序员乔戈里

美团程序员的笔试题(美团面试官问我一个字符)(1)

美团程序员的笔试题(美团面试官问我一个字符)(2)

美团程序员的笔试题(美团面试官问我一个字符)(3)

美团程序员的笔试题(美团面试官问我一个字符)(4)

美团程序员的笔试题(美团面试官问我一个字符)(5)

美团程序员的笔试题(美团面试官问我一个字符)(6)

美团程序员的笔试题(美团面试官问我一个字符)(7)

public class testT { public static void main(String [] args){ String A = "hi你是乔戈里"; System.out.println(A.length()); } }

以上结果输出为7。

美团程序员的笔试题(美团面试官问我一个字符)(8)


美团程序员的笔试题(美团面试官问我一个字符)(9)

美团程序员的笔试题(美团面试官问我一个字符)(10)

美团程序员的笔试题(美团面试官问我一个字符)(11)

美团程序员的笔试题(美团面试官问我一个字符)(12)

美团程序员的笔试题(美团面试官问我一个字符)(13)


小萌边说边在IDEA中的win环境下选中String.length()函数,使用ctrl B快捷键进入到String.length()的定义。

/** * Returns the length of this string. * The length is equal to the number of <a href="Character.html#Unicode">Unicode * code units</a> in the string. * * @return the length of the sequence of characters represented by this * object. */ public int length() { return value.length; }

接着使用google翻译对这段英文进行了翻译,得到了大体意思:返回字符串的长度,这一长度等于字符串中的 Unicode 代码单元的数目。

小萌:乔戈里,那这又是啥意思呢?乔哥:前几天我写的一篇文章:[https://mp.weixin.qq.com/s/Zn-BnMd2tohHPpvMhLFYxw](https://mp.weixin.qq.com/s/Zn-BnMd2tohHPpvMhLFYxw)里面对于Java的字符使用的编码有介绍:

Java中 有内码和外码这一区分简单来说

而java内码:unicode(utf-16)中使用的是utf-16.所以上面的那句话再进一步解释就是:返回字符串的长度,这一长度等于字符串中的UTF-16的代码单元的数目。

美团程序员的笔试题(美团面试官问我一个字符)(14)

美团程序员的笔试题(美团面试官问我一个字符)(15)


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!

美团程序员的笔试题(美团面试官问我一个字符)(16)

美团程序员的笔试题(美团面试官问我一个字符)(17)

美团程序员的笔试题(美团面试官问我一个字符)(18)

美团程序员的笔试题(美团面试官问我一个字符)(19)

来看个例子!

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())); } }

美团程序员的笔试题(美团面试官问我一个字符)(20)

可以看到通过codePointCount()函数得知这个音乐字符是一个字符!

美团程序员的笔试题(美团面试官问我一个字符)(21)


几个问题:0.codePointCount是什么意思呢?1.之前不是说音符字符是“U 1D11E”,为什么UTF-16是"uD834uDD1E",这俩之间如何转换?2.前面说了UTF-16的代码单元,UTF-32和UTF-8的代码单元是多少呢?

美团程序员的笔试题(美团面试官问我一个字符)(22)

一个一个解答:

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


美团程序员的笔试题(美团面试官问我一个字符)(23)

上图是对应的转换规则:

第2个问题


美团程序员的笔试题(美团面试官问我一个字符)(24)


参考

本文首发于程序员乔戈里


,