【Java】 基礎(chǔ)篇 -- 字符 char

char 在 Java 中是個(gè)很底層的東西了,比如 String 郑现、StringBuilder 的底層就是它,但是在我們平時(shí)的工作中呢荧降,很少使用他接箫,不過(guò)既然是底層,今天我們大家就來(lái)一起研究下這 “哥們”朵诫。


char 用來(lái)表示 ==1 個(gè)字符== 辛友。也就是說(shuō),如果你寫 2個(gè)字符剪返,那么這里是會(huì)報(bào)錯(cuò)的瞎领。如下:

// 這種編譯報(bào)錯(cuò) Too many characters in character literal
char c = '中國(guó)';

當(dāng)然 char 也可以用來(lái)表示中文字符。在賦值時(shí)随夸,我們經(jīng)常這樣表示:


 char c = '中';
        
 char c1 = 'H';

但是這里就會(huì)遇到一些面試上的坑了九默,比如使用字符類型進(jìn)行算術(shù)運(yùn)算和比較運(yùn)算? 這是個(gè)什么鬼 A + B == 宾毒?驼修??

其實(shí)在 Java 內(nèi)部進(jìn)行字符處理時(shí)诈铛,采用的是 Unicode乙各,(這里插一句 對(duì) Unicode 和 UTF-X 的理解,Unicode 是一個(gè)包含世界各國(guó)字母的字符列表的編碼幢竹。 Universal Multiple-Octet Coded Character Set”耳峦,簡(jiǎn)稱 UCS, 俗稱 “unicode “,就是每一個(gè)字母對(duì)應(yīng)一個(gè)編碼 ID焕毫,是一種映射關(guān)系蹲坷,我們可以理解為 Unicode 是 一個(gè)標(biāo)準(zhǔn)驶乾,一個(gè)規(guī)則,而 UTF-X 則是一種具體的對(duì) Unicode 的實(shí)現(xiàn)循签,UTF-X 是一種 針對(duì) Unicode 的可變長(zhǎng)度字符編碼级乐,也是一種前綴碼,是一種編碼格式县匠。它可以用來(lái)表 示Unicode標(biāo)準(zhǔn)中的任何字符风科,而且 UTF-8 是兼容 ASCII 的。UTF-8 是 Unicode 的 實(shí)現(xiàn)方式之一乞旦。)

char 本質(zhì)上是一個(gè)固定占用 2 個(gè)字節(jié)的無(wú)符號(hào)正整數(shù)贼穆,對(duì)應(yīng) Unicode, 也就是說(shuō) 上面 的 李兰粉, H 都分別對(duì)應(yīng)一個(gè) 正整數(shù)扮惦,char 只能表示 Unicode 編號(hào)在 65 536 以內(nèi)的字符。因?yàn)橐粋€(gè)字節(jié) 只能表示 256 個(gè)符號(hào)亲桦,2 個(gè)字節(jié)就是 256 x 256 = 65536 個(gè)符號(hào)崖蜜。那么如果超出范圍該咋表示呢,用 2 個(gè)char?颓汀Tチ臁!


既然了解完了 Unicode舔琅,那么每個(gè)字符都可以用一個(gè) 對(duì)應(yīng)的 編碼ID 表示等恐,也就是 一個(gè)正整數(shù)。既然是數(shù)字了备蚓,自然可以進(jìn)行算術(shù)運(yùn)算和比較運(yùn)算课蔬。

char 的 二進(jìn)制轉(zhuǎn)換

下面我們就以 Integer 的轉(zhuǎn)換二進(jìn)制函數(shù) toBinaryString 為例,說(shuō)明一下 char 字節(jié)在 Java 中如何轉(zhuǎn)換二進(jìn)制的郊尝。

    public static void main(String[] args) {
        char c = '中';
        System.out.println(Integer.toBinaryString(c));
       // 二進(jìn)制為:  100111000101101
    }

我們給 char 賦值一個(gè) 中文 字節(jié) 中二跋,然后求出它的 二進(jìn)制。

Integer 的 toBinaryString 方法:

    /**
     *   返回 輸入?yún)?shù) i 的 二進(jìn)制字符串
     */
    public static String toBinaryString(int i) {
        return toUnsignedString0(i, 1);
    }

這里調(diào)用了 toUnsignedString0流昏, 如下


   /**
     * Convert the integer to an unsigned number.
     * 轉(zhuǎn)換一個(gè) 整型到一個(gè)無(wú)符號(hào)二進(jìn)制數(shù)字
     */
    private static String toUnsignedString0(int val, int shift) {
        // 這里斷言忽略
        // assert shift > 0 && shift <=5 : "Illegal shift value";
        // Integer.numberOfLeadingZeros 返回?zé)o符號(hào)整型的最高非零位前面的0的個(gè)數(shù)扎即,包括符號(hào)位在內(nèi)
        // 比如 Integer.numberOfLeadingZeros(10) 結(jié)果是 28
        // Integer.SIZE 為 32
        int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
        int chars = Math.max(((mag + (shift - 1)) / shift), 1);
        char[] buf = new char[chars];

        // 這里是整個(gè)方法的核心,整數(shù)轉(zhuǎn)換二進(jìn)制况凉,然后更新 char 的緩沖
        formatUnsignedInt(val, shift, buf, 0, chars);

        // Use special constructor which takes over "buf".
        return new String(buf, true);
    }

核心轉(zhuǎn)換函數(shù) formatUnsignedInt 如下:

   /**
     * 格式化到字符緩沖區(qū)
     * @param val 被格式化的數(shù)
     * @param shift 格式化的類型 (4 代表16進(jìn)制, 3 代表8進(jìn)制, 1 代表二進(jìn)制)
     * @param buf 待寫入的字符緩沖區(qū)
     * @param offset 字符開(kāi)始的位置
     * @param len 要寫的字符數(shù)
     * @return the lowest character  location used
     */
   static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
        int charPos = len;
        int radix = 1 << shift;
        int mask = radix - 1;
        do {
            // 二進(jìn)制的 & 運(yùn)算谚鄙,求出下標(biāo),然后獲取 digits 中對(duì)應(yīng)的值刁绒,寫入 buf 緩沖區(qū)
            // final static char[] digits = {
            //               '0' , '1' , '2' , '3' , '4' , '5' ,
            //               '6' , '7' , '8' , '9' , 'a' , 'b' ,
            //               'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
            //               'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
            //               'o' , 'p' , 'q' , 'r' , 's' , 't' ,
            //               'u' , 'v' , 'w' , 'x' , 'y' , 'z'
    }
            buf[offset + --charPos] = Integer.digits[val & mask];
            // 無(wú)符號(hào)右移
            val >>>= shift;
        } while (val != 0 && charPos > 0);
        return charPos;
    }

通過(guò)上面的代碼可以看出闷营,Integer 內(nèi)部維護(hù)了一個(gè) char 數(shù)組,我們的普通字符轉(zhuǎn)換 二進(jìn)制的時(shí)候知市,都是求出 digits 某個(gè)下標(biāo)的值傻盟,然后寫到緩沖區(qū)速蕊,以 String 的形式返回給用戶的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末莫杈,一起剝皮案震驚了整個(gè)濱河市互例,隨后出現(xiàn)的幾起案子奢入,更是在濱河造成了極大的恐慌筝闹,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腥光,死亡現(xiàn)場(chǎng)離奇詭異关顷,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)武福,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門议双,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人捉片,你說(shuō)我怎么就攤上這事平痰。” “怎么了伍纫?”我有些...
    開(kāi)封第一講書人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵宗雇,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我莹规,道長(zhǎng)赔蒲,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任良漱,我火速辦了婚禮舞虱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘母市。我一直安慰自己矾兜,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布患久。 她就那樣靜靜地躺著焕刮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪墙杯。 梳的紋絲不亂的頭發(fā)上配并,一...
    開(kāi)封第一講書人閱讀 49,837評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音高镐,去河邊找鬼溉旋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛嫉髓,可吹牛的內(nèi)容都是我干的观腊。 我是一名探鬼主播邑闲,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼梧油!你這毒婦竟也來(lái)了苫耸?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤儡陨,失蹤者是張志新(化名)和其女友劉穎褪子,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體骗村,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嫌褪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了胚股。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片笼痛。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖琅拌,靈堂內(nèi)的尸體忽然破棺而出缨伊,到底是詐尸還是另有隱情,我是刑警寧澤进宝,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布刻坊,位于F島的核電站,受9級(jí)特大地震影響即彪,放射性物質(zhì)發(fā)生泄漏紧唱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一隶校、第九天 我趴在偏房一處隱蔽的房頂上張望漏益。 院中可真熱鬧,春花似錦深胳、人聲如沸绰疤。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)轻庆。三九已至,卻和暖如春敛劝,著一層夾襖步出監(jiān)牢的瞬間余爆,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工夸盟, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蛾方,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像桩砰,于是被迫代替她去往敵國(guó)和親拓春。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 字符是用戶可以讀寫的最小單位。計(jì)算機(jī)所能支持的字符組成的集合煮纵,就叫做字符集懂鸵。字符集通常以二維表的形式存在。二維表的...
    劉惜有閱讀 8,091評(píng)論 2 14
  • 網(wǎng)站亂碼問(wèn)題我們會(huì)經(jīng)常碰到醉途,大多見(jiàn)于非英文的中文字符或其他字符亂碼矾瑰,而且砖茸,這類問(wèn)題常常是因?yàn)榫幋a方式問(wèn)題隘擎,主要原因...
    波段頂?shù)?/span>閱讀 2,836評(píng)論 1 9
  • 每一個(gè)不經(jīng)世事的女生都曾是天使 只是后來(lái)誤落凡間,經(jīng)世俗打磨成為了普羅大眾的人凉夯。 網(wǎng)上鋪天蓋地...
    做一個(gè)庸俗的人閱讀 501評(píng)論 5 8
  • 當(dāng)初能做成 現(xiàn)今如何靜如此 再也沒(méi)有為你準(zhǔn)備好的資料货葬,你學(xué)完就基本全懂了 有的是不斷有新挑戰(zhàn),住房劲够,獨(dú)自生活震桶,工作...
    Zgmdada閱讀 157評(píng)論 0 0
  • 套期保值,那只是投機(jī)的一種借口而已征绎。 直到飛機(jī)平穩(wěn)的落地北京機(jī)場(chǎng)蹲姐,肖遙還一直覺(jué)得自己好像仍舊是在做夢(mèng)之中。從臨時(shí)決...
    luozi閱讀 197評(píng)論 0 0