char类型和Unicode编码
生活随笔
收集整理的這篇文章主要介紹了
char类型和Unicode编码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【0】README
0.1)本文對?char類型和Unicode編碼 的總結并不完整,僅供參考;
0.2)本文獲取Unicode輔助字符的代碼點的idea轉自:?
http://blog.csdn.net/xujinsmile/article/details/8526387?,?
http://bbs.csdn.net/topics/340195349?,?http://blog.csdn.net/longyulu/article/details/7374862;
【1】char 類型 1)char類型:它用于表示單個字符, 通常用來表示字符常量; 2)Unicode編碼單元:?它可以表示為16進制值, 其范圍從 \u0000 ~ \uffff; 如\u03C0 表示希臘字母 π; 3)轉移序列: 3.1)除了可以采用轉義序列符 \u 表示Unicode 代碼單元的編碼外, 還有一些用于表示特殊字符的轉移序列符,看下表: 3.2)所有這些轉義序列符都可以出現在字符常量或字符串的引號內;如'\u2122' 和 "hello\n"; 3.3)轉移序列符 \u 還可以出現在 字符常量或字符串的引號之外(其他的轉移序列不可以), 如 public static void main(String \u005B\u005D args) ,其中?\u005B 和 \u005D 是 '[' 和 ']' 的編碼; 4)出現的問題+解決方法(引入Unicode編碼): 4.1)要想弄清char類型, 就必須了解Unicode編碼表(干貨——引入了Unicode編碼表)。Unicode打破了傳統字符編碼的限制。在Unicode出現之前, 已經有許多不同的標準:美國的ASCII、西歐語言的ISO、中國的GB 18030 和 BIG-5 等,?這樣就產生了兩個問題:一是對于任意給定的代碼值,在不同的編碼方案下有可能對應不同的字母; 二是采用大字符集的語言其編碼長度有可能不同;(如一些字符采用單字節編碼,而另一些字符采用多字節編碼) 4.2)如何解決:人們認為兩個字節的代碼寬度足以能夠對世界上各種語言的所有字符進行編碼, 并有足夠的空間留給未來的擴展; 4.3)1991年,發布的Unicode1.0 : 僅占用了 65535個代碼值中不到一半的部分,在設計Java時 決定采用16位的Unicode 字符集;但是后來Unicode 增加了對漢語、日語和韓語的處理使得字符個數超過了 65536, 這樣使得 Java的16位的 char 類型已經不能滿足描述所有 Unicode字符的需要了; 5)下面用專業術語解釋Java語言解決這個問題的基本方法: 5.1)代碼點:?從JDK5.0開始, 代碼點是指與一個編碼表中的某個字符對應的代碼值;在Unicode標準中, 代碼點采用16進制書寫,并加上前綴 U+, 例如 U+0041 表示字符A的代碼點;(干貨——代碼點的定義) 5.2)代碼級別:Unicode的代碼點可以分成17 個代碼級別, 第一個代碼級別稱為基本的多語言級別, 代碼點從 U+0000~U+FFFF;其余的16個附加級別,代碼點從U+10000~U+10FFFF, 其中包括了一些輔助字符;(干貨——代碼級別的定義) 5.3)代碼單元:在UTF-16中, 每個字符用16位表示,這叫一個代碼單元;而輔助字符采用一對連續的代碼單元進行編碼;(干貨——代碼單元的定義,一個Unicode代碼單元==16位==2個字節) 5.4)這樣構成的編碼值:一定落入基本的多語言級別中空閑的2048字節內,通常被替代區域(U+D800~U+DBFF用于第一個代碼單元,而U+DC00~U+DFFF用于第二個代碼單元)。這樣的設計十分巧妙,我們可以從中迅速知道一個代碼單元是一個字符編碼,還是一個輔助字符的第一或第二部分。 看個Unicode字符的編碼荔枝)對于整數集合的數學符號Z, 它的代碼點是 U+1D56B,并且是用兩個代碼單元U+D835 和 U+DD6B 編碼的;(具體參見?https://en.wikipedia.org/wiki/UTF-16) 6)Java采用UTF-16:在Java中, char類型用 UTF-16 編碼描述一個代碼單元;(干貨——char類型用UTF-16 編碼描述一個代碼單元,char類型就是一個Unicode代碼單元, Unicode碼元==Unicode代碼單元) 7)Warning)我們強烈建議,不要在程序中使用char類型, 除非確實需要對 UTF-16代碼單元進行操作。最好將 需要處理的字符串用抽象數據類型表示;
【2】Unicode編碼中的代碼點和代碼單元? 1)Java 字符串由char 序列組成: char數據類型是一個采用 UTF-16 編碼表示 Unicode代碼點的代碼單元, 大多數的常用 Unicode字符使用一個代碼單元就可以表示, 而輔助字符需要一對代碼單元表示; 2)length方法:?它將返回采用 UTF-16 編碼表示的給定字符串所需要的代碼單元數量; 3)看荔枝: package com.tomcat.test;public class UnicodeTest {public static void main1(String[] args) {String greeting = "hello";System.out.println(greeting.length()); // Unicode代碼單元(碼元)數量 // 5int codePointCount = greeting.codePointCount(0, greeting.length());System.out.println(codePointCount); //Unicode代碼點數量 // 5char first = greeting.charAt(0);// 返回位置0的代碼單元 // 'h'System.out.println(first);// 要想得到第i個代碼點for (int i = 0; i < greeting.length(); i++) {int index = greeting.offsetByCodePoints(0, i);int codePoint = greeting.codePointAt(index);System.out.println("index = " + index + ", codePoint = " + codePoint + ", " + (char)codePoint);}/*** output* 55hindex = 0, cp = 104, hindex = 1, cp = 101, eindex = 2, cp = 108, lindex = 3, cp = 108, lindex = 4, cp = 111, o*/}public static void main2(String[] args) {String sentence = "\u1D56B is the set of integers";for (int i = 0; i < sentence.length();) {int codePoint = sentence.codePointAt(i);if(Character.isSupplementaryCodePoint(codePoint)) {i += 2;} else {i++;}System.out.println(codePoint + ", " + (char)codePoint);}}public static void main3(String...args){ char[] ch = Character.toChars(0x10400); System.out.printf("U+10400 高代理字符: %04x\n", (int)ch[0]);//d801 System.out.printf("U+10400 低代理字符: %04x\n", (int)ch[1]);//dc00 String str = new String(ch); System.out.println("代碼單元長度: " + str.length());//2 System.out.println("代碼點數量: " + str.codePointCount(0, str.length()));//1 System.out.println(str.codePointAt(0));//返回給定位置開始或結束的代碼點,66560 System.out.println(str.charAt(1));//返回給定位置的代碼單元,由于未定義,返回? //遍歷一個字符串,打印出所有字符的代碼點 str += "Hello,world!"; int i = 0; int cp = str.codePointAt(i); while(i < str.length()){ System.out.println(str.codePointAt(i) + ", " + (char)str.codePointAt(i)); if(Character.isSupplementaryCodePoint(cp)) i += 2;//如果cp所在的位置是代碼點的第一部分,執行此處 else i++; } /* * 66560 * 72 * 108 * 111 * 119 * 114 * 100 */ } }
【1】char 類型 1)char類型:它用于表示單個字符, 通常用來表示字符常量; 2)Unicode編碼單元:?它可以表示為16進制值, 其范圍從 \u0000 ~ \uffff; 如\u03C0 表示希臘字母 π; 3)轉移序列: 3.1)除了可以采用轉義序列符 \u 表示Unicode 代碼單元的編碼外, 還有一些用于表示特殊字符的轉移序列符,看下表: 3.2)所有這些轉義序列符都可以出現在字符常量或字符串的引號內;如'\u2122' 和 "hello\n"; 3.3)轉移序列符 \u 還可以出現在 字符常量或字符串的引號之外(其他的轉移序列不可以), 如 public static void main(String \u005B\u005D args) ,其中?\u005B 和 \u005D 是 '[' 和 ']' 的編碼; 4)出現的問題+解決方法(引入Unicode編碼): 4.1)要想弄清char類型, 就必須了解Unicode編碼表(干貨——引入了Unicode編碼表)。Unicode打破了傳統字符編碼的限制。在Unicode出現之前, 已經有許多不同的標準:美國的ASCII、西歐語言的ISO、中國的GB 18030 和 BIG-5 等,?這樣就產生了兩個問題:一是對于任意給定的代碼值,在不同的編碼方案下有可能對應不同的字母; 二是采用大字符集的語言其編碼長度有可能不同;(如一些字符采用單字節編碼,而另一些字符采用多字節編碼) 4.2)如何解決:人們認為兩個字節的代碼寬度足以能夠對世界上各種語言的所有字符進行編碼, 并有足夠的空間留給未來的擴展; 4.3)1991年,發布的Unicode1.0 : 僅占用了 65535個代碼值中不到一半的部分,在設計Java時 決定采用16位的Unicode 字符集;但是后來Unicode 增加了對漢語、日語和韓語的處理使得字符個數超過了 65536, 這樣使得 Java的16位的 char 類型已經不能滿足描述所有 Unicode字符的需要了; 5)下面用專業術語解釋Java語言解決這個問題的基本方法: 5.1)代碼點:?從JDK5.0開始, 代碼點是指與一個編碼表中的某個字符對應的代碼值;在Unicode標準中, 代碼點采用16進制書寫,并加上前綴 U+, 例如 U+0041 表示字符A的代碼點;(干貨——代碼點的定義) 5.2)代碼級別:Unicode的代碼點可以分成17 個代碼級別, 第一個代碼級別稱為基本的多語言級別, 代碼點從 U+0000~U+FFFF;其余的16個附加級別,代碼點從U+10000~U+10FFFF, 其中包括了一些輔助字符;(干貨——代碼級別的定義) 5.3)代碼單元:在UTF-16中, 每個字符用16位表示,這叫一個代碼單元;而輔助字符采用一對連續的代碼單元進行編碼;(干貨——代碼單元的定義,一個Unicode代碼單元==16位==2個字節) 5.4)這樣構成的編碼值:一定落入基本的多語言級別中空閑的2048字節內,通常被替代區域(U+D800~U+DBFF用于第一個代碼單元,而U+DC00~U+DFFF用于第二個代碼單元)。這樣的設計十分巧妙,我們可以從中迅速知道一個代碼單元是一個字符編碼,還是一個輔助字符的第一或第二部分。 看個Unicode字符的編碼荔枝)對于整數集合的數學符號Z, 它的代碼點是 U+1D56B,并且是用兩個代碼單元U+D835 和 U+DD6B 編碼的;(具體參見?https://en.wikipedia.org/wiki/UTF-16) 6)Java采用UTF-16:在Java中, char類型用 UTF-16 編碼描述一個代碼單元;(干貨——char類型用UTF-16 編碼描述一個代碼單元,char類型就是一個Unicode代碼單元, Unicode碼元==Unicode代碼單元) 7)Warning)我們強烈建議,不要在程序中使用char類型, 除非確實需要對 UTF-16代碼單元進行操作。最好將 需要處理的字符串用抽象數據類型表示;
【2】Unicode編碼中的代碼點和代碼單元? 1)Java 字符串由char 序列組成: char數據類型是一個采用 UTF-16 編碼表示 Unicode代碼點的代碼單元, 大多數的常用 Unicode字符使用一個代碼單元就可以表示, 而輔助字符需要一對代碼單元表示; 2)length方法:?它將返回采用 UTF-16 編碼表示的給定字符串所需要的代碼單元數量; 3)看荔枝: package com.tomcat.test;public class UnicodeTest {public static void main1(String[] args) {String greeting = "hello";System.out.println(greeting.length()); // Unicode代碼單元(碼元)數量 // 5int codePointCount = greeting.codePointCount(0, greeting.length());System.out.println(codePointCount); //Unicode代碼點數量 // 5char first = greeting.charAt(0);// 返回位置0的代碼單元 // 'h'System.out.println(first);// 要想得到第i個代碼點for (int i = 0; i < greeting.length(); i++) {int index = greeting.offsetByCodePoints(0, i);int codePoint = greeting.codePointAt(index);System.out.println("index = " + index + ", codePoint = " + codePoint + ", " + (char)codePoint);}/*** output* 55hindex = 0, cp = 104, hindex = 1, cp = 101, eindex = 2, cp = 108, lindex = 3, cp = 108, lindex = 4, cp = 111, o*/}public static void main2(String[] args) {String sentence = "\u1D56B is the set of integers";for (int i = 0; i < sentence.length();) {int codePoint = sentence.codePointAt(i);if(Character.isSupplementaryCodePoint(codePoint)) {i += 2;} else {i++;}System.out.println(codePoint + ", " + (char)codePoint);}}public static void main3(String...args){ char[] ch = Character.toChars(0x10400); System.out.printf("U+10400 高代理字符: %04x\n", (int)ch[0]);//d801 System.out.printf("U+10400 低代理字符: %04x\n", (int)ch[1]);//dc00 String str = new String(ch); System.out.println("代碼單元長度: " + str.length());//2 System.out.println("代碼點數量: " + str.codePointCount(0, str.length()));//1 System.out.println(str.codePointAt(0));//返回給定位置開始或結束的代碼點,66560 System.out.println(str.charAt(1));//返回給定位置的代碼單元,由于未定義,返回? //遍歷一個字符串,打印出所有字符的代碼點 str += "Hello,world!"; int i = 0; int cp = str.codePointAt(i); while(i < str.length()){ System.out.println(str.codePointAt(i) + ", " + (char)str.codePointAt(i)); if(Character.isSupplementaryCodePoint(cp)) i += 2;//如果cp所在的位置是代碼點的第一部分,執行此處 else i++; } /* * 66560 * 72 * 108 * 111 * 119 * 114 * 100 */ } }
總結
以上是生活随笔為你收集整理的char类型和Unicode编码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tomcat(4)Tomcat的默认连接
- 下一篇: tomcat(5)servlet容器