今天粗略读了一下Character的代码,总结如下:
1. 定义了一些 UnicodeSubset (UnicodeBlock) , 每一个UnicodeBlock 代表一个代码段(范围),一部分代码段表示一个UnicodeScript, 任何一个CodePoint都属于某一个UnicodeScript,但不一定属于某一个UnicodeBlock(因为有些代码段不属于任何subset or block--block的name 为null ,这种情况下UnicodeScript就是"UNASSIGNED")
2. 不是很理解为什么 public static UnicodeScript of(int codePoint) 用了 Arrays.binarySearch 而 public static UnicodeBlock of(int codePoint) 却是自己写的二分算法。
UnicodeScript的算法:
- int index = Arrays.binarySearch(scriptStarts, codePoint);
- if (index < 0)
- index = -index - 2;
- return scripts[index];
int index = Arrays.binarySearch(scriptStarts, codePoint);
if (index < 0)
index = -index - 2;
return scripts[index];
UnicodeBlock的算法:
- int top, bottom, current;
- bottom = 0;
- top = blockStarts.length;
- current = top/2;
- // invariant: top > current >= bottom && codePoint >= unicodeBlockStarts[bottom]
- while (top - bottom > 1) {
- if (codePoint >= blockStarts[current]) {
- bottom = current;
- } else {
- top = current;
- }
- current = (top + bottom) / 2;
- }
- return blocks[current];
int top, bottom, current;
bottom = 0;
top = blockStarts.length;
current = top/2;
// invariant: top > current >= bottom && codePoint >= unicodeBlockStarts[bottom]
while (top - bottom > 1) {
if (codePoint >= blockStarts[current]) {
bottom = current;
} else {
top = current;
}
current = (top + bottom) / 2;
}
return blocks[current];
3. 为 0-127 (BASIC_LATIN , LATIN_1_SUPPLEMENT, LATIN_EXTENDED_A) 的Code Point建了cache pool, 这个范围的Character new出来都是单例。
4. isValidCodePoint 用了一个简易的小tricky 优化了一下:
- // Optimized form of:
- // codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT
- int plane = codePoint >>> 16;
- return plane < ((MAX_CODE_POINT + 1) >>> 16);
// Optimized form of:
// codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT
int plane = codePoint >>> 16;
return plane < ((MAX_CODE_POINT + 1) >>> 16);
5. public static int charCount(int codePoint) 没有validate codePoint, 如果codePoint为负数时,也返回1就不太对了。
6. isJavaIdentifierStart 和 isJavaIdentifierPart 可以用来判断一个字符可不可以用来作为Java标识符的开头和部分。
7. 字母 A-Z 可以用来表示基数为10 以上的进制中的一位digit。forDigit方法用来获得某个进制中某字母代表的digit,而digit方法可以得到某个进制中某个digit用哪个字母表示。
8. unicode 为字符定义了一个数值,比如‘A’是10 , ‘Ⅸ’ 是9, 可以用 getNumericValue方法得到一个Code Point的该值。
9. isWiteSpace方法用来判断某个Code Point是不是Java认为的空白字符。
10. isMirrored用来判断字符是否具有镜面对称的字符。比如'(' , '['.
11. 提供了一个 非public 的static char[] toUpperCaseCharArray(int codePoint) 是因为unicode 规定在 BMP中的unicode可能出现其大写是双字符的情况。比如 ß 的大写是 SS。这个方法会被String使用,所以只有String的toUpperCase会将ß 变成SS,而Character不行。
12. getName用来得到Code Point的名称,比如Character.getName(' ') 就是 SPACE, 对于没有名称的character就用它的UnicodeBlock名(下划线用空格替换)加上Code Point代码。比如 Character.getName('\uD801') 就是 HIGH SURROGATES D801。如果没有UnicodeBlock,就返回null。