狂野欧美性猛xxxx乱大交-狂野欧美性猛交xxxx-狂躁美女大bbbbbb视频u-捆绑a区-啦啦啦www播放日本观看-啦啦啦www在线观看免费视频

二維碼
企資網(wǎng)

掃一掃關(guān)注

當(dāng)前位置: 首頁 » 企資快報(bào) » 精準(zhǔn) » 正文

一個(gè)字符串中到底能有多少個(gè)字符?我竟然算錯(cuò)了

放大字體  縮小字體 發(fā)布日期:2021-09-25 09:09:57    作者:本站原創(chuàng)    瀏覽次數(shù):21
導(dǎo)讀

依照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 si

依照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è)例子:

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

輸出結(jié)果:

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

    String.length返回Unicode code units的長度。String.toCharArray返回字符數(shù)組。

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

      普通的中文字:字符串的長度是2,每個(gè)中文字按UTF-8編碼是三個(gè)字節(jié),字符數(shù)組的長度看起來也沒問題emojis字符:我們設(shè)置了兩個(gè)emojis字符,男女頭像。結(jié)果字符串的長度是4, UTF-8編碼8個(gè)字節(jié),字符數(shù)組的長度是4生僻的中文字:我們設(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è)字符對應(yīng)一個(gè)編碼點(diǎn)(一個(gè)整數(shù)),用 U+緊跟著十六進(jìn)制數(shù)表示。所有字符按照使用上的頻繁度劃分為 17 個(gè)平面(編號為 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è)唯一的編號數(shù)字,稱之為碼點(diǎn)值或碼點(diǎn)編號,除開某些特殊區(qū)域(比如代理區(qū)、專用區(qū))的非字符代碼點(diǎn)和保留代碼點(diǎn),每個(gè)代碼點(diǎn)唯一對應(yīng)于一個(gè)字符。從U+0000 到 U+10FFFF。Code Unit:代碼單元,是指一個(gè)已編碼的文本中具有蕞短的比特組合的單元。對于 UTF-8 來說,代碼單元是 8 比特長;對于 UTF-16 來說,代碼單元是 16 比特長。換一種說法就是 UTF-8 的是以一個(gè)字節(jié)為蕞小單位的,UTF-16 是以兩個(gè)字節(jié)為蕞小單位的。

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

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

        其實(shí)是不會的, 幸運(yùn)的是, 在BMP平面中, U+D800到U+DFFF之間的碼位是永久保留不映射到Unicode字符,UTF-16就利用保留下來的0xD800-0xDFFF區(qū)塊的碼位來對幫助平面的字符的碼位進(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平面中不用來映射的碼位,所以不會產(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>

        我們在進(jìn)行字符串截取的時(shí)候,比如String.substring有可能會踩到一些坑,尤其經(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值。

 
(文/本站原創(chuàng))
免責(zé)聲明
本文僅代表作發(fā)布者:本站原創(chuàng)個(gè)人觀點(diǎn),本站未對其內(nèi)容進(jìn)行核實(shí),請讀者僅做參考,如若文中涉及有違公德、觸犯法律的內(nèi)容,一經(jīng)發(fā)現(xiàn),立即刪除,需自行承擔(dān)相應(yīng)責(zé)任。涉及到版權(quán)或其他問題,請及時(shí)聯(lián)系我們刪除處理郵件:weilaitui@qq.com。
 

Copyright ? 2016 - 2025 - 企資網(wǎng) 48903.COM All Rights Reserved 粵公網(wǎng)安備 44030702000589號

粵ICP備16078936號

微信

關(guān)注
微信

微信二維碼

WAP二維碼

客服

聯(lián)系
客服

聯(lián)系客服:

在線QQ: 303377504

客服電話: 020-82301567

E_mail郵箱: weilaitui@qq.com

微信公眾號: weishitui

客服001 客服002 客服003

工作時(shí)間:

周一至周五: 09:00 - 18:00

反饋

用戶
反饋

主站蜘蛛池模板: 男人天堂欧美 | 成人免费视频在线 | 亚洲网站免费 | 青青久草在线视频 | 色狠狠婷婷97 | 免费网站看v片在线成人国产系列 | 一级毛片老太婆交性欧美 | 日本免费人成黄页网观看视频 | 国产精品手机在线观看 | www.天天干| 欧美日本亚洲国产一区二区 | 欧美日韩国产在线成人网 | 亚洲精品一区国产二区 | 奇米影视在线观看 | 狠狠操狠狠操狠狠操 | 国产成人久久精品二区三区牛 | 久久久精品成人免费看 | 久久九色综合九色99伊人 | 国产亚洲一级精品久久 | 91精品国产99久久 | 日本一级特黄毛片高清视频 | 97欧美在线看欧美视频免费 | 97影院秋霞国产精品 | 欧美一级毛片欧美毛片视频 | 6一10周岁毛片免费 6一10周岁毛片在线 | 欧美日本一道高清免费3区 欧美日本一道免费一区三区 | 亚洲v欧美 | 久久伊人免费视频 | 亚洲精品精品 | 999国产精品视频 | 夜夜夜夜夜夜夜工噜噜噜 | 老司机福利免费 | 久久国产免费福利资源网站 | 一级毛片成人免费看免费不卡 | 国产第113页 | 国产欧美一区二区三区免费 | 国内免费一区二区三区视频 | 毛片2016免费视频 | 精品少妇一区二区三区视频 | 国产理论最新国产精品视频 | 夜夜夜爽爽爽久久久 |