java.lang.String有2个方法
char | charAt(int index)
Returns the
char value at the specified index.
|
int | codePointAt(int index)
Returns the character (Unicode code point) at the specified index.
|
仔细看一下这2个方法的描述,正常来说应该会产生一个疑问,char和unicode code point有什么区别?(懂unicode的除外)
可能很多人都知道,java使用的是unicode,其实大部分人都分不清ucs和utf,准确地说java使用的是utf-16编码,而utf-16编码表达的是ucs。这个细节的不同,导致了一个普遍的误解:字符串在java中存储时每个字符占一个存储位置。实际上utf-16可以表达整个ucs-4字符集,只是BMP的字符恰好用1个16位整数存储(在这个区域里,中文文字只有20,927个),而其它平面的字符用2个16位整数存储而已。
也就是说,在某些少见的情况下,String.length()比字符串的长度要长。可以运行一下下面的代码找找感觉。
package test;
public class Test {
public static String str = "\uD800\uDC00a汉";
public static void main(String[] args) {
System.out.printf("str.length(): %d\n", str.length());
System.out.printf("str.codePointCount(0, 1): %d\n", str.codePointCount(0, 1));
System.out.printf("str.codePointCount(0, 2): %d\n", str.codePointCount(0, 2));
System.out.printf("str.codePointCount(0, 3): %d\n", str.codePointCount(0, 3));
System.out.printf("str.codePointCount(0, str.length()): %d\n", str.codePointCount(0, str.length()));
System.out.printf("str: %s\n", str);
System.out.printf("str.charAt(0): %c\n", str.charAt(0));
System.out.printf("str.codePointAt(0): %d\n", str.codePointAt(0));
System.out.printf("str.codePointAt(1): %d\n", str.codePointAt(1));
}
}
最后一个问题,知道这个有什么用?这个问题很难回答。按照80/20法则,解决20%的关键问题可以适用80%的场景。抽象一点讲,每个问题了解90%(大多数情况下是到不了这么高的),在16个问题叠加的情况下,能够完整解决的概率是0.1853,所以为什么我们觉得自己懂很多,还是写不好代码。在每个细节上多懂一点,有助于自己工作能轻松一点。但是,你永远无法预测的是,在你解决的每个问题中,是你知道的那十万个细节中的哪一个拯救了你。