Mar*_*eon 36 java unicode character-encoding
Java char是2个字节(最大大小为65,536)但是有95,221个 Unicode字符.这是否意味着您无法在Java应用程序中处理某些Unicode字符?
这可归结为您使用的字符编码吗?
ken*_*ytm 35
如果你足够小心,你可以处理它们.
Java char是一个UTF-16代码单元.对于代码点> 0xFFFF的字符,它将被编码为2 char秒(代理对).
有关如何在Java中处理这些字符,请参阅http://www.oracle.com/us/technologies/java/supplementary-142654.html.
(顺便说一句,在Unicode 5.2中,1,114,112个插槽中有107,154个指定的字符.)
Mic*_*rdt 14
Java使用UTF-16.单个Java char只能表示基本多语言平面中的字符.其他角色必须由两个代理对表示char.这反映在API方法中,例如String.codePointAt().
是的,这意味着当与基本多语言平面之外的字符一起使用时,许多Java代码会以某种方式破坏.
leo*_*loy 13
要添加其他答案,需要记住一些要点:
一个Java的char需要总是16位.
一个Unicode字符,当为UTF-16编码,以"几乎总是"(不总是)16位:这是因为有超过64K Unicode字符.因此,Java char不是Unicode字符(虽然"几乎总是").
"几乎总是",在上面,表示Unicode的64K第一个代码点,范围0x0000到0xFFFF(BMP),在UTF-16编码中占16位.
非BMP("罕见")Unicode字符表示为两个Java字符(代理表示).这也适用于作为字符串的文字表示:例如,字符U + 20000被写为"\ uD840\uDC00".
Corolary:string.length()返回java字符的数量,而不是Unicode字符的数量.只返回一个"罕见"unicode字符(例如U + 20000)的字符串length() = 2.相同的考虑适用于处理char序列的任何方法.
Java几乎没有处理非BMP unicode字符的智能.有一些实用方法将字符视为代码点,表示为int,例如:Character.isLetter(int ch).这些是真正的全Unicode方法.
你说:
Java char 是 2 个字节(最大大小为 65,536),但有 95,221 个 Unicode 字符。
实际上,Unicode 中定义的字符库存急剧增加。Unicode 继续增长——不仅仅是因为表情符号。
char 是遗产该char类型早已过时,现在是legacy。
相反,您应该使用代码点编号。
你问:
这是否意味着您无法在 Java 应用程序中处理某些 Unicode 字符?
该char类型可以处理不到今天的 Unicode 字符的一半。
要表示任何 Unicode 字符,请使用代码点编号。永远不要使用char.
Unicode 中的每个字符都分配有一个代码点编号。这些范围超过一百万,从 0 到 1,114,112。在与上面列出的数字进行比较时进行数学计算,这意味着该范围内的大多数数字尚未分配给一个字符。其中一些号码被保留为私人使用区,永远不会被分配。
该String班已获得方法与码点号的工作,为做Character课。
通过从零开始的索引号获取字符串中任何字符的代码点号。在这里,我们得到97了这封信a。
int codePoint = "Cat".codePointAt( 1 ) ; // 97 = 'a', hex U+0061, LATIN SMALL LETTER A.
Run Code Online (Sandbox Code Playgroud)
对于更通用CharSequence而不是String,请使用Character.codePointAt.
我们可以获得代码点编号的 Unicode 名称。
String name = Character.getName( 97 ) ; // letter `a`
Run Code Online (Sandbox Code Playgroud)
拉丁文小写字母 A
我们可以得到一个字符串中所有字符的代码点编号的流。
IntStream codePointsStream = "Cat".codePoints() ;
Run Code Online (Sandbox Code Playgroud)
我们可以把它转换成一个List的Integer对象。请参阅如何将 Java 8 IntStream 转换为列表?.
List< Integer > codePointsList = codePointsStream.boxed().collect( Collectors.toList() ) ;
Run Code Online (Sandbox Code Playgroud)
可以String通过调用将任何代码点编号更改为单个字符的 a Character.toString。
String s = Character.toString( 97 ) ; // 97 is `a`, LATIN SMALL LETTER A.
Run Code Online (Sandbox Code Playgroud)
一种
我们可以String从一个IntStream代码点编号生成一个对象。请参阅从代码点编号的 IntStream 创建字符串?.
IntStream intStream = IntStream.of( 67 , 97 , 116 , 32 , 128_008 ); // 32 = SPACE, 128,008 = CAT (emoji).
String output =
intStream
.collect( // Collect the results of processing each code point.
StringBuilder :: new , // Supplier<R> supplier
StringBuilder :: appendCodePoint , // ObjIntConsumer<R> accumulator
StringBuilder :: append // BiConsumer<R,?R> combiner
) // Returns a `CharSequence` object.
.toString(); // If you would rather have a `String` than `CharSequence`, call `toString`.
Run Code Online (Sandbox Code Playgroud)
猫
你问:
这是否归结为您使用的字符编码?
在内部,StringJava 中的 a 始终使用UTF-16。
在从 Java 字符串导入或导出文本时,您只能使用其他字符编码。
所以,回答你的问题,不,字符编码在这里没有直接关系。将文本放入 Java 后String,它采用 UTF-16 编码,因此可以包含任何 Unicode 字符。当然,要查看该字符,您必须使用带有为该特定字符定义的字形的字体。
从 Java 字符串导出文本时,如果指定的旧字符编码无法表示文本中使用的某些 Unicode 字符,则会出现问题。所以使用现代字符编码,现在意味着UTF-8因为UTF-16 现在被认为是有害的。
| 归档时间: |
|
| 查看次数: |
42114 次 |
| 最近记录: |