日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

面试:一个 Java 字符串到底有多少个字符?

發(fā)布時(shí)間:2025/3/21 java 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试:一个 Java 字符串到底有多少个字符? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

依照J(rèn)ava的文檔, Java中的字符內(nèi)部是以UTF-16編碼方式表示的,最小值是?\u0000?(0),最大值是\uffff(65535), 也就是一個(gè)字符以2個(gè)字節(jié)來表示,難道Java最多只能表示 65535個(gè)字符?

char: The char data type is a single 16-bit Unicode character. It has a minimum value of '\u0000' (or 0) and a maximum value of '\uffff' (or 65,535 inclusive).

from The Java? Tutorials

首先,讓我們先看個(gè)例子:

public?class?Main?{public?static?void?main(String[]?args)?{//?中文常見字String?s?=?"你好";System.out.println("1.?string?length?="?+?s.length());System.out.println("1.?string?bytes?length?="?+?s.getBytes().length);System.out.println("1.?string?char?length?="?+?s.toCharArray().length);System.out.println();//?emojiss?=?"👦👩";System.out.println("2.?string?length?="?+?s.length());System.out.println("2.?string?bytes?length?="?+?s.getBytes().length);System.out.println("2.?string?char?length?="?+?s.toCharArray().length);System.out.println();//?中文生僻字s?=?"𡃁妹";System.out.println("3.?string?length?="?+?s.length());System.out.println("3.?string?bytes?length?="?+?s.getBytes().length);System.out.println("3.?string?char?length?="?+?s.toCharArray().length);System.out.println();} }

運(yùn)行這個(gè)程序,你覺得輸出結(jié)果是什么?

輸出結(jié)果:

1.?string?length?=2 1.?string?bytes?length?=6 1.?string?char?length?=22.?string?length?=4 2.?string?bytes?length?=8 2.?string?char?length?=43.?string?length?=3 3.?string?bytes?length?=7 3.?string?char?length?=3

我們知道,?String.getBytes()如果不指定編碼格式,Java會(huì)使用操作系統(tǒng)的編碼格式得到字節(jié)數(shù)組,在我的MacOS中,默認(rèn)使用UTF-8作為字符編碼(locale命令可以查看操作系統(tǒng)的編碼),所以在我的機(jī)器運(yùn)行,String.getBytes()會(huì)返回UTF-8編碼的字節(jié)數(shù)組。

String.length返回Unicode code units的長度。

String.toCharArray返回字符數(shù)組。

我們?cè)O(shè)置的字符串都是兩個(gè)unicode字符,輸出結(jié)果:

  • 普通的中文字:字符串的長度是2,每個(gè)中文字按UTF-8編碼是三個(gè)字節(jié),字符數(shù)組的長度看起來也沒問題

  • emojis字符:我們?cè)O(shè)置了兩個(gè)emojis字符,男女頭像。結(jié)果字符串的長度是4,?UTF-8編碼8個(gè)字節(jié),字符數(shù)組的長度是4

  • 生僻的中文字:我們?cè)O(shè)置了兩個(gè)中文字,其中一個(gè)是生僻的中文字。結(jié)果字符串的長度是3,?UTF-8編碼7個(gè)字節(jié),字符數(shù)組的長度是3

看起來字符串的字符數(shù)和我們預(yù)期的有點(diǎn)不一樣,我們的字符串只有兩個(gè)unicode字符, 可是輸出結(jié)果有時(shí)候是2,有時(shí)候是3, 有時(shí)候是4,為什么呢?這還得從Java的歷史說起。

Java最初設(shè)計(jì)的Charactor用兩個(gè)字節(jié)來表示unicode字符,這沒有問題, 因?yàn)樽畛鮱nicode中的字符還比較少, Java 1.1之前采用Unicode version 1.1.5, JDK 1.1中支持Unicode 2.0, JDK 1.1.7支持Unicode 2.1, Java SE 1.4 支持?Unicode 3.0, Java SE 5.0開始支持Unicode 4.0。

直到Unicode 3.0, Java用兩個(gè)字節(jié)來表示unicode字符還沒有問題,因?yàn)閁nicode 3.0最多49,259個(gè)字符, 兩個(gè)字節(jié)可以表示65,535個(gè)字符,還足夠容的下所有的uicode3.0字符。

但是Unicode 4.0(事實(shí)上自Unicode 3.1), 字符集進(jìn)行很大的擴(kuò)充,已經(jīng)達(dá)到了96,447個(gè)字符,Unicode 11.0已經(jīng)包含137,374個(gè)字符。

在Unicode中,為每一個(gè)字符對(duì)應(yīng)一個(gè)編碼點(diǎn)(一個(gè)整數(shù)),用 U+緊跟著十六進(jìn)制數(shù)表示。所有字符按照使用上的頻繁度劃分為 17 個(gè)平面(編號(hào)為 0-16),即基本的多語言平面和增補(bǔ)平面。基本的多語言平面(英文為 Basic Multilingual Plane,簡稱 BMP)又稱平面 0,收集了使用最廣泛的字符。

這樣一來,Java的Charactor的兩個(gè)字節(jié)的設(shè)計(jì),已經(jīng)不足以容納所有的Unicode 4的字符, 所以可能需要4個(gè)字節(jié)才能表示擴(kuò)展字符,所以現(xiàn)在的Charactor代表的已經(jīng)不再是一個(gè)字符?(代碼點(diǎn) code point), 而是一個(gè)代碼單元(code unit)。

  • Code Point: 代碼點(diǎn),一個(gè)字符的數(shù)字表示。一個(gè)字符集一般可以用一張或多張由多個(gè)行和多個(gè)列所構(gòu)成的二維表來表示。二維表中行與列交叉的點(diǎn)稱之為代碼點(diǎn),每個(gè)碼點(diǎn)分配一個(gè)唯一的編號(hào)數(shù)字,稱之為碼點(diǎn)值或碼點(diǎn)編號(hào),除開某些特殊區(qū)域(比如代理區(qū)、專用區(qū))的非字符代碼點(diǎn)和保留代碼點(diǎn),每個(gè)代碼點(diǎn)唯一對(duì)應(yīng)于一個(gè)字符。從U+0000?到?U+10FFFF。

  • Code Unit:代碼單元,是指一個(gè)已編碼的文本中具有最短的比特組合的單元。對(duì)于 UTF-8 來說,代碼單元是 8 比特長;對(duì)于 UTF-16 來說,代碼單元是 16 比特長。換一種說法就是 UTF-8 的是以一個(gè)字節(jié)為最小單位的,UTF-16 是以兩個(gè)字節(jié)為最小單位的。

Java的字符在內(nèi)部以UTF-16編碼方式來表示,String.length返回的是Code Unit的長度,而不再是Unicode中字符的長度。對(duì)于傳統(tǒng)的BMP平面的代碼點(diǎn),String.length和我們傳統(tǒng)理解的字符的數(shù)量是一致的,對(duì)于擴(kuò)展的字符,String.length可能是我們理解的字符長度的兩倍。

有可能你會(huì)問, 對(duì)于一個(gè)UTF-16編碼的擴(kuò)展字符,它以4個(gè)字節(jié)來表示,那么前兩個(gè)字節(jié)會(huì)不會(huì)和BMP平面沖突,導(dǎo)致程序不知道它是擴(kuò)展字符還是BMP平面的字符?

其實(shí)是不會(huì)的, 幸運(yùn)的是, 在BMP平面中,?U+D800到U+DFFF之間的碼位是永久保留不映射到Unicode字符,UTF-16就利用保留下來的0xD800-0xDFFF區(qū)塊的碼位來對(duì)輔助平面的字符的碼位進(jìn)行編碼。

UTF-16編碼中,輔助平面中的碼位從U+10000到U+10FFFF,共計(jì)FFFFF個(gè),需要20位來表示。第一個(gè)整數(shù)(兩個(gè)字節(jié),稱為前導(dǎo)代理)要容納上述20位的前10位,第二個(gè)整數(shù)(稱為后尾代理)容納上述20位的后10位。前導(dǎo)代理的值的范圍是0xD800到0xDBFF,后尾代理的0xDC00~0xDFFF。可以看到前導(dǎo)代理和后尾代理的范圍都落在了BMP平面中不用來映射的碼位,所以不會(huì)產(chǎn)生沖突,而且前導(dǎo)代理和后尾代理也沒有重合。這樣我們得到兩個(gè)字節(jié)的,就可以直接判斷它是否是BMP平面的字符,還是擴(kuò)展字符中的前導(dǎo)代理還是后尾代碼。

國外的有些用戶用emojis字符做自己的昵稱,導(dǎo)致有些系統(tǒng)不能正確的顯示出來,這是因?yàn)檫@些系統(tǒng)粗暴的使用Charactor來表示,在顯示的時(shí)候截?cái)嗟臅r(shí)候有時(shí)候可能不是在正確的代碼點(diǎn)上進(jìn)行截?cái)唷?/p>

我們?cè)谶M(jìn)行字符串截取的時(shí)候,比如String.substring有可能會(huì)踩到一些坑,尤其經(jīng)常使用的emojis字符。

自 Java 1.5 java.lang.String就提供了Code Point方法, 用來獲取完整的Unicode字符和Unicode字符數(shù)量:

  • public int codePointAt(int index)

  • public int codePointBefore(int index)

  • public int codePointCount(int beginIndex, int endIndex)

注意這些方法中的index使用的是code unit值。

總結(jié)

以上是生活随笔為你收集整理的面试:一个 Java 字符串到底有多少个字符?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 青青草久久久 | 国产激情一区 | 一级片一级 | av先锋在线| h视频免费在线 | 午夜偷拍福利 | 国产肉体xxxx裸体784大胆 | 国产一级高清 | 人妻色综合网站 | 国产情侣免费视频 | 欧美日韩中字 | 亚洲免费看黄 | 中国色老太hd | 蜜桃av在线播放 | 一级特黄a大片免费 | 国产伦精品一区二区三区高清版 | aaaaaav| 久久只有精品 | 成人三级在线视频 | 国产啊v在线观看 | a极黄色片 | 欧美8888| 四虎精品在线 | 国产精品一区二区三区在线播放 | 毛片网站视频 | 国产农村妇女毛片精品久久 | 天天摸天天干 | 精品一区在线视频 | 久久99婷婷 | 色综合中文网 | 久久精工是国产品牌吗 | 高h视频在线播放 | 一本av在线 | 久久免费视频6 | 精品久久无码中文字幕 | 久久久久精 | 久久久久久少妇 | 深爱婷婷网| 国产91免费看 | 九九精品视频在线 | 欧美日日夜夜 | 国产在线视频你懂得 | 中文字幕高清在线免费播放 | 成人午夜大片 | 欧美抠逼视频 | 91在线无精精品入口 | 日韩欧美高清在线观看 | 天天干干干 | 亚洲熟妇av一区二区三区漫画 | 草久久久 | av一级免费 | 欧美成人高清视频 | 人与嘼交av免费 | 姐姐av | 国产一区=区 | 偷拍青青草 | av黄在线观看 | 久久黄色| 欧美午夜一区二区 | 中文字幕人妻一区 | 免费看av软件 | 亚洲欧美另类图片 | 天天综合久久 | 国产一区二区在线播放视频 | 久久99日韩 | 天天做日日干 | 香港三日本8a三级少妇三级99 | 五月天开心激情 | 国产精品色婷婷99久久精品 | 无码国内精品人妻少妇蜜桃视频 | 中文字幕中文在线 | 91丨porny丨露出| 麻豆av一区二区三区在线观看 | 嫩草精品 | 国产第一网站 | 中文字幕在线资源 | 偷偷操av | 欧美一区二区日韩一区二区 | 国产三级全黄裸体 | 999精品国产 | av网站不卡 | 中文字幕五码 | 欧美人与禽猛交乱配 | 国产午夜无码精品免费看奶水 | 亚洲a精品 | 久久精品一区二区 | 精品人妻一区二区色欲产成人 | 精品久久久久久一区二区里番 | 99久久亚洲精品日本无码 | 国产精品偷乱一区二区三区 | 噜噜色av| 日本一级三级三级三级 | 久久久久久蜜桃 | 成年人免费看的视频 | 久久精品黄色片 | 久久久www成人免费精品 | 毛片手机在线 | 免费av片| 亚洲精品av中文字幕在线在线 |