天天看點

深入學習java源碼之Character.Subset與Character.UnicodeBlock

深入學習java源碼之Character.Subset與Character.UnicodeBlock

hashMap的加載因子

new HashMap<>(128);

public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }
           

加載因子 loadfactor

/**
     * 預設的初始化的容量,必須是2的幂次數<br>
     * The default initial capacity - MUST be a power of two.
     */
    static final int DEFAULT_INITIAL_CAPACITY = 16;

    /**
     * 預設的加載因子
     */
    static final float DEFAULT_LOAD_FACTOR = 0.75f;

    /**
     * 門檻值。等于容量乘以加載因子。<br>
     * 也就是說,一旦容量到了這個數值,HashMap将會擴容。
     * The next size value at which to resize (capacity * load factor).
     * @serial
     */
    int threshold;
           

加載因子越高   空間使用率提高了  但是查詢時間 和添加時間增加

加載因子 loadfactor 是表示 Hsah 表中元素的填滿的程度.若:加載因子越大,填滿的元素越多,好處是,空間使用率高了,但:沖突的機會加大了.反之,加載因子越小,填滿的元素越少,好處是:沖突的機會減小了,但:空間浪費多了.

沖突的機會越大,則查找的成本越高.反之,查找的成本越小.因而,查找時間就越小.

是以,必須在 “沖突的機會”與”空間使用率”之間尋找一種平衡與折衷. 這種平衡與折衷本質上是資料結構中有名的”時-空”沖突的平衡與折衷.

預設的容量是 16,而 threshold 是 16*0.75 = 12;

深入學習java源碼之Character.Subset與Character.UnicodeBlock

hashmap 是這樣存的

先利用hashcode  找到需要存的地方

但是 存的地方肯定是有限的 就是hashMap配置設定到的空間  比如是  10

現在你 第一個元素來了 那麼他會根據 你 hashcode%10 得到你 在 10個位置中該存到哪裡

這個時候就有一個問題,就是,如果hashcode%10 找到存的地方   當你要存進去時候 你發現裡面已經有另外一個對象了,

那麼這時候就要調用 equals方法 進行比較,如果相同,就說明是一個相同的對象。就替換掉。

如果不同,那麼就 形成散列桶,  就是2個對象一起, 不過有先後, 後進來的 在後面。

hashmap 查詢對象,要的是效率,直接通過hashcode找到存放的位址,直接取出,隻需一次。

但是像我們前面說的這種情況,是會讓操作數增加的,

你找到了 hashcode 所對應的實體位址,發現裡面有2個對象, 這時就不能确定那個是你要找的,那麼就要通過equals和你傳入的key進行比對,相同 則傳回。

前面的講述已經發現  當你空間隻有僅僅為10的時候 是很容易造成,2個對象的hashcode 所對應的位址是一個位置的情況

這樣就造成 2個 對象 會形成散列桶,使查詢和插入的時間增加。

這時就有一個加載因子的參數,如果加載因子為0.75 ,如果你hashmap的 空間有 100  那麼  當你插入了75個元素的時候 hashmap就需要擴容了,不然的話 會形成很長散列桶 , 對于查詢和插入都會增加時間,因為 他要一個一個的equals。

但是你又不能讓加載因子很小,0.01 這樣是不合适的,因為 他會大大消耗你的 記憶體, 你一加入一個對象hashmap就擴容。

java的enum枚舉

原始的接口定義常量

public interface IConstants {
    String MON = "Mon";
    String TUE = "Tue";
    String WED = "Wed";
    String THU = "Thu";
    String FRI = "Fri";
    String SAT = "Sat";
    String SUN = "Sun";
}
           

建立枚舉類型要使用 enum 關鍵字,隐含了所建立的類型都是 java.lang.Enum 類的子類(java.lang.Enum 是一個抽象類)。枚舉類型符合通用模式 

Class Enum<E extends Enum<E>>

,而 

E

 表示枚舉類型的名稱。枚舉類型的每一個值都将映射到 

protected Enum(String name, int ordinal)

 構造函數中,在這裡,每個值的名稱都被轉換成一個字元串,并且序數設定表示了此設定被建立的順序。

public enum EnumTest {
    MON, TUE, WED, THU, FRI, SAT, SUN;
}
           

這段代碼實際上調用了7次 Enum(String name, int ordinal):

new Enum<EnumTest>("MON",0);
new Enum<EnumTest>("TUE",1);
new Enum<EnumTest>("WED",2);
    ... ...
           
public class Test {
    public static void main(String[] args) {
        for (EnumTest e : EnumTest.values()) {
            System.out.println(e.toString());
        }
         
        System.out.println("----------------我是分隔線------------------");
         
        EnumTest test = EnumTest.TUE;
        switch (test) {
        case MON:
            System.out.println("今天是星期一");
            break;
        case TUE:
            System.out.println("今天是星期二");
            break;
        // ... ...
        default:
            System.out.println(test);
            break;
        }
    }
}


MON
TUE
WED
THU
FRI
SAT
SUN
----------------我是分隔線------------------
今天是星期二
           

 可以把 enum 看成是一個普通的 class,它們都可以定義一些屬性和方法,不同之處是:enum 不能使用 extends 關鍵字繼承其他類,因為 enum 已經繼承了 java.lang.Enum(java是單一繼承)。

enum 對象的常用方法介紹

int 

compareTo(E o)

          比較此枚舉與指定對象的順序。

Class<E> 

getDeclaringClass()

          傳回與此枚舉常量的枚舉類型相對應的 Class 對象。

String 

name()

          傳回此枚舉常量的名稱,在其枚舉聲明中對其進行聲明。

int 

ordinal()

          傳回枚舉常量的序數(它在枚舉聲明中的位置,其中初始常量序數為零)。

String 

toString()

          傳回枚舉常量的名稱,它包含在聲明中。

static 

<T extends Enum<T>> T 

valueOf(Class<T> enumType, String name)

          傳回帶指定名稱的指定枚舉類型的枚舉常量。

public class Test {
    public static void main(String[] args) {
        EnumTest test = EnumTest.TUE;
         
        //compareTo(E o)
        switch (test.compareTo(EnumTest.MON)) {
        case -1:
            System.out.println("TUE 在 MON 之前");
            break;
        case 1:
            System.out.println("TUE 在 MON 之後");
            break;
        default:
            System.out.println("TUE 與 MON 在同一位置");
            break;
        }
         
        //getDeclaringClass()
        System.out.println("getDeclaringClass(): " + test.getDeclaringClass().getName());
         
        //name() 和  toString()
        System.out.println("name(): " + test.name());
        System.out.println("toString(): " + test.toString());
         
        //ordinal(), 傳回值是從 0 開始
        System.out.println("ordinal(): " + test.ordinal());
    }
}



TUE 在 MON 之後
getDeclaringClass(): com.test.EnumTest
name(): TUE
toString(): TUE
ordinal(): 1
           
Modifier and Type Method and Description

static int

charCount(int codePoint)

确定代表指定字元(Unicode代碼點)所需的

char

值。

char

charValue()

傳回此

Character

對象的值。

static int

codePointAt(char[] a, int index)

傳回

char

數組的給定索引處的代碼點。

static int

codePointAt(char[] a, int index, int limit)

傳回

char

數組的給定索引處的代碼點,其中隻能使用

index

小于

limit

數組元素。

static int

codePointAt(CharSequence seq, int index)

傳回

CharSequence

給定索引處的代碼點。

static int

codePointBefore(char[] a, int index)

傳回

char

陣列給定索引之前的代碼點。

static int

codePointBefore(char[] a, int index, int start)

傳回

char

陣列給定索引之前的代碼點,隻能使用

index

大于等于

start

數組元素。

static int

codePointBefore(CharSequence seq, int index)

傳回的給定索引前面的代碼點

CharSequence

static int

codePointCount(char[] a, int offset, int count)

傳回

char

數組參數的子陣列中的Unicode代碼點數。

static int

codePointCount(CharSequence seq, int beginIndex, int endIndex)

傳回指定字元序列的文本範圍内的Unicode代碼點數。

static int

compare(char x, char y)

數值比較兩個

char

數值。

int

compareTo(Character anotherCharacter)

數字比較兩個

Character

對象。

static int

digit(char ch, int radix)

傳回指定基數中字元

ch

的數值。

static int

digit(int codePoint, int radix)

傳回指定基數中指定字元(Unicode代碼點)的數值。

boolean

equals(Object obj)

将此對象與指定對象進行比較。

static char

forDigit(int digit, int radix)

确定指定基數中特定數字的字元表示。

static byte

getDirectionality(char ch)

傳回給定字元的Unicode方向屬性。

static byte

getDirectionality(int codePoint)

傳回給定字元的Unicode方向性屬性(Unicode代碼點)。

static String

getName(int codePoint)

傳回指定字元的Unicode名稱

codePoint

,或者如果代碼點是空

unassigned

static int

getNumericValue(char ch)

傳回指定的Unicode字元代表的

int

值。

static int

getNumericValue(int codePoint)

傳回

int

值指定字元(Unicode代碼點)表示。

static int

getType(char ch)

傳回一個值,表示一個字元的一般類别。

static int

getType(int codePoint)

傳回一個值,表示一個字元的一般類别。

int

hashCode()

傳回這個

Character

的哈希碼; 等于調用

charValue()

的結果。

static int

hashCode(char value)

傳回一個

char

值的哈希碼; 相容

Character.hashCode()

static char

highSurrogate(int codePoint)

傳回主導替代(一個 high surrogate code unit所述的) surrogate pair表示在UTF-16編碼指定的補充的字元(Unicode代碼點)。

static boolean

isAlphabetic(int codePoint)

确定指定的字元(Unicode代碼點)是否是字母表。

static boolean

isBmpCodePoint(int codePoint)

确定指定的字元(Unicode代碼點)是否在 Basic Multilingual Plane (BMP)中 。

static boolean

isDefined(char ch)

确定字元是否以Unicode定義。

static boolean

isDefined(int codePoint)

确定Unicode中是否定義了一個字元(Unicode代碼點)。

static boolean

isDigit(char ch)

确定指定的字元是否是數字。

static boolean

isDigit(int codePoint)

确定指定的字元(Unicode代碼點)是否為數字。

static boolean

isHighSurrogate(char ch)

确定給定的

char

值是否為 Unicode high-surrogate code unit (也稱為 引導代理單元 )。

static boolean

isIdentifierIgnorable(char ch)

确定指定的字元是否應被視為Java辨別符或Unicode辨別符中的可忽略字元。

static boolean

isIdentifierIgnorable(int codePoint)

确定指定字元(Unicode代碼點)是否應被視為Java辨別符或Unicode辨別符中的可忽略字元。

static boolean

isIdeographic(int codePoint)

确定指定字元(Unicode代碼點)是否是Unicode标準定義的CJKV(中文,日文,韓文和越南文)表意文字。

static boolean

isISOControl(char ch)

确定指定的字元是否是ISO控制字元。

static boolean

isISOControl(int codePoint)

确定引用的字元(Unicode代碼點)是否是ISO控制字元。

static boolean

isJavaIdentifierPart(char ch)

确定指定的字元是否可以是Java辨別符的一部分,而不是第一個字元。

static boolean

isJavaIdentifierPart(int codePoint)

确定字元(Unicode代碼點)可能是Java辨別符的一部分,而不是第一個字元。

static boolean

isJavaIdentifierStart(char ch)

确定指定字元是否允許作為Java辨別符中的第一個字元。

static boolean

isJavaIdentifierStart(int codePoint)

确定字元(Unicode代碼點)是否允許作為Java辨別符中的第一個字元。

static boolean

isJavaLetter(char ch)

已棄用

替換為isJavaIdentifierStart(char)。

static boolean

isJavaLetterOrDigit(char ch)

已棄用

由isJavaIdentifierPart(char)替代。

static boolean

isLetter(char ch)

确定指定的字元是否是一個字母。

static boolean

isLetter(int codePoint)

确定指定的字元(Unicode代碼點)是否是一個字母。

static boolean

isLetterOrDigit(char ch)

确定指定的字元是字母還是數字。

static boolean

isLetterOrDigit(int codePoint)

确定指定的字元(Unicode代碼點)是字母還是數字。

static boolean

isLowerCase(char ch)

确定指定的字元是否是小寫字元。

static boolean

isLowerCase(int codePoint)

确定指定的字元(Unicode代碼點)是否是小寫字元。

static boolean

isLowSurrogate(char ch)

确定給定的

char

值是否為 Unicode low-surrogate code unit (也稱為 尾随代理單元 )。

static boolean

isMirrored(char ch)

根據Unicode規範确定字元是否鏡像。

static boolean

isMirrored(int codePoint)

确定是否根據Unicode規範鏡像指定的字元(Unicode代碼點)。

static boolean

isSpace(char ch)

已棄用

替換為isWhitespace(char)。

static boolean

isSpaceChar(char ch)

确定指定的字元是否是Unicode空格字元。

static boolean

isSpaceChar(int codePoint)

确定指定字元(Unicode代碼點)是否為Unicode空格字元。

static boolean

isSupplementaryCodePoint(int codePoint)

确定指定字元(Unicode代碼點)是否在 supplementary character範圍内。

static boolean

isSurrogate(char ch)

确定給定的

char

值是否是Unicode 代理代碼單元 。

static boolean

isSurrogatePair(char high, char low)

确定指定的一對

char

值是否有效 Unicode surrogate pair 。

static boolean

isTitleCase(char ch)

确定指定的字元是否是一個titlecase字元。

static boolean

isTitleCase(int codePoint)

确定指定的字元(Unicode代碼點)是否是一個titlecase字元。

static boolean

isUnicodeIdentifierPart(char ch)

确定指定的字元是否可以是Unicode辨別符的一部分,而不是第一個字元。

static boolean

isUnicodeIdentifierPart(int codePoint)

确定指定的字元(Unicode代碼點)是否可能是Unicode辨別符的一部分,而不是第一個字元。

static boolean

isUnicodeIdentifierStart(char ch)

确定指定字元是否允許為Unicode辨別符中的第一個字元。

static boolean

isUnicodeIdentifierStart(int codePoint)

确定Unicode辨別符中的第一個字元是否允許指定的字元(Unicode代碼點)。

static boolean

isUpperCase(char ch)

确定指定的字元是否為大寫字元。

static boolean

isUpperCase(int codePoint)

确定指定的字元(Unicode代碼點)是否為大寫字元。

static boolean

isValidCodePoint(int codePoint)

确定指定的代碼點是否有效 Unicode code point value 。

static boolean

isWhitespace(char ch)

根據Java确定指定的字元是否為空格。

static boolean

isWhitespace(int codePoint)

根據Java确定指定字元(Unicode代碼點)是否為空格。

static char

lowSurrogate(int codePoint)

傳回尾随替代(一個 low surrogate code unit所述的) surrogate pair表示在UTF-16編碼指定的補充的字元(Unicode代碼點)。

static int

offsetByCodePoints(char[] a, int start, int count, int index, int codePointOffset)

傳回給定的

char

子陣列中的索引,該子陣列與

index

codePointOffset

代碼點偏移。

static int

offsetByCodePoints(CharSequence seq, int index, int codePointOffset)

傳回給定的char序列中與

index

codePointOffset

代碼點偏移的索引。

static char

reverseBytes(char ch)

傳回通過反轉指定的 char值中的位元組順序獲得的值。

static char[]

toChars(int codePoint)

将指定的字元(Unicode代碼點)轉換為存儲在

char

數組中的UTF-16

char

形式。

static int

toChars(int codePoint, char[] dst, int dstIndex)

将指定的字元(Unicode代碼點)轉換為其UTF-16表示形式。

static int

toCodePoint(char high, char low)

将指定的代理對轉換為其補充代碼點值。

static char

toLowerCase(char ch)

使用UnicodeData檔案中的大小寫映射資訊将字元參數轉換為小寫。

static int

toLowerCase(int codePoint)

使用UnicodeData檔案中的大小寫映射資訊将字元(Unicode代碼點)參數轉換為小寫。

String

toString()

傳回

String

表示此對象

Character

的價值。

static String

toString(char c)

傳回一個

String

對象,表示指定的

char

static char

toTitleCase(char ch)

使用UnicodeData檔案中的案例映射資訊将字元參數轉換為titlecase。

static int

toTitleCase(int codePoint)

使用UnicodeData檔案中的案例映射資訊将字元(Unicode代碼點)參數轉換為titlecase。

static char

toUpperCase(char ch)

使用UnicodeData檔案中的案例映射資訊将字元參數轉換為大寫。

static int

toUpperCase(int codePoint)

使用UnicodeData檔案中的案例映射資訊将字元(Unicode代碼點)參數轉換為大寫。

static Character

valueOf(char c)

傳回一個 表示指定的 char值的 Character執行個體。

java源碼

package java.lang;

import java.util.Arrays;
import java.util.Map;
import java.util.HashMap;
import java.util.Locale;


public final
class Character implements java.io.Serializable, Comparable<Character> {

    public static final int MIN_RADIX = 2;

    public static final int MAX_RADIX = 36;
	
    public static final char MIN_VALUE = '\u0000';	
	
    public static final char MAX_VALUE = '\uFFFF';
	
    @SuppressWarnings("unchecked")
    public static final Class<Character> TYPE = (Class<Character>) Class.getPrimitiveClass("char");

    public static final byte UNASSIGNED = 0;

    public static final byte UPPERCASE_LETTER = 1;	

    public static final byte LOWERCASE_LETTER = 2;
	
	......
	
    public static final byte DECIMAL_DIGIT_NUMBER = 9;
	
    static final int ERROR = 0xFFFFFFFF;
	
    public static final byte DIRECTIONALITY_UNDEFINED = -1;	
	
    public static final char MIN_HIGH_SURROGATE = '\uD800';
	
    public static final char MIN_LOW_SURROGATE  = '\uDC00';
	
    public static final char MIN_SURROGATE = MIN_HIGH_SURROGATE;
	
    public static final char MAX_SURROGATE = MAX_LOW_SURROGATE;
	
    public static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000;

    private final char value;

    private static final long serialVersionUID = 3786198910865385080L;
	
    public Character(char value) {
        this.value = value;
    }

    private static class CharacterCache {
        private CharacterCache(){}

        static final Character cache[] = new Character[127 + 1];

        static {
            for (int i = 0; i < cache.length; i++)
                cache[i] = new Character((char)i);
        }
    }

    public static Character valueOf(char c) {
        if (c <= 127) { // must cache
            return CharacterCache.cache[(int)c];
        }
        return new Character(c);
    }

    public char charValue() {
        return value;
    }
	
    @Override
    public int hashCode() {
        return Character.hashCode(value);
    }	
	
    public static int hashCode(char value) {
        return (int)value;
    }

    public boolean equals(Object obj) {
        if (obj instanceof Character) {
            return value == ((Character)obj).charValue();
        }
        return false;
    }
	
    public String toString() {
        char buf[] = {value};
        return String.valueOf(buf);
    }

    public static String toString(char c) {
        return String.valueOf(c);
    }
	
    public static int getType(char ch) {
        return getType((int)ch);
    }

    public static int getType(int codePoint) {
        return CharacterData.of(codePoint).getType(codePoint);
    }
	
    public static int compare(char x, char y) {
        return x - y;
    }	
	
    public int compareTo(Character anotherCharacter) {
        return compare(this.value, anotherCharacter.value);
    }	
	
    public static final int BYTES = SIZE / Byte.SIZE;	
	
    public static final int SIZE = 16;	
	
    public static String getName(int codePoint) {
        if (!isValidCodePoint(codePoint)) {
            throw new IllegalArgumentException();
        }
        String name = CharacterName.get(codePoint);
        if (name != null)
            return name;
        if (getType(codePoint) == UNASSIGNED)
            return null;
        UnicodeBlock block = UnicodeBlock.of(codePoint);
        if (block != null)
            return block.toString().replace('_', ' ') + " "
                   + Integer.toHexString(codePoint).toUpperCase(Locale.ENGLISH);
        // should never come here
        return Integer.toHexString(codePoint).toUpperCase(Locale.ENGLISH);
    }
	
    public static class Subset  {

        private String name;	
	
        protected Subset(String name) {
            if (name == null) {
                throw new NullPointerException("name");
            }
            this.name = name;
        }
        public final boolean equals(Object obj) {
            return (this == obj);
        }	
        public final int hashCode() {
            return super.hashCode();
        }	
        public final String toString() {
            return name;
        }
    }
	
    public static final class UnicodeBlock extends Subset {

        private static Map<String, UnicodeBlock> map = new HashMap<>(256);

        /**
         * Creates a UnicodeBlock with the given identifier name.
         * This name must be the same as the block identifier.
         */
        private UnicodeBlock(String idName) {
            super(idName);
            map.put(idName, this);
        }

        private UnicodeBlock(String idName, String alias) {
            this(idName);
            map.put(alias, this);
        }

        private UnicodeBlock(String idName, String... aliases) {
            this(idName);
            for (String alias : aliases)
                map.put(alias, this);
        }

        public static final UnicodeBlock  BASIC_LATIN =
            new UnicodeBlock("BASIC_LATIN",
                             "BASIC LATIN",
                             "BASICLATIN");		
							 
        public static final UnicodeBlock ARMENIAN =
            new UnicodeBlock("ARMENIAN");		

        public static final UnicodeBlock PHAGS_PA =
            new UnicodeBlock("PHAGS_PA",
                             "PHAGS-PA");
							 
        private static final int blockStarts[] = {
            0x0000,   // 0000..007F; Basic Latin
            0x0080,   // 0080..00FF; Latin-1 Supplement
            0x0100,   // 0100..017F; Latin Extended-A
            0x0180,   // 0180..024F; Latin Extended-B
            0x0250,   // 0250..02AF; IPA Extensions
		};

        private static final UnicodeBlock[] blocks = {
            BASIC_LATIN,
            LATIN_1_SUPPLEMENT,
            LATIN_EXTENDED_A,
            LATIN_EXTENDED_B,							 
        };	
		
        public static UnicodeBlock of(char c) {
            return of((int)c);
        }

        public static UnicodeBlock of(int codePoint) {
            if (!isValidCodePoint(codePoint)) {
                throw new IllegalArgumentException();
            }

            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];
        }	

        public static final UnicodeBlock forName(String blockName) {
            UnicodeBlock block = map.get(blockName.toUpperCase(Locale.US));
            if (block == null) {
                throw new IllegalArgumentException();
            }
            return block;
        }		
}							 

    public static enum UnicodeScript {
        /**
         * Unicode script "Common".
         */
        COMMON,

        /**
         * Unicode script "Latin".
         */
        LATIN,

        /**
         * Unicode script "Greek".
         */
        GREEK,
		/**
         * Unicode script "Takri".
         */
        TAKRI,

        /**
         * Unicode script "Miao".
         */
        MIAO,

        /**
         * Unicode script "Unknown".
         */
        UNKNOWN;

        private static final int[] scriptStarts = {
            0x0000,   // 0000..0040; COMMON
            0x0041,   // 0041..005A; LATIN
            0x005B,   // 005B..0060; COMMON
            0x0061,   // 0061..007A; LATIN
            0x20000,  // 20000..E0000; HAN
            0xE0001,  // E0001..E00FF; COMMON
            0xE0100,  // E0100..E01EF; INHERITED
            0xE01F0   // E01F0..10FFFF; UNKNOWN
        };

        private static final UnicodeScript[] scripts = {
            COMMON,
            LATIN,
            COMMON,
            LATIN,
            COMMON,	
            INHERITED,
            UNKNOWN
        };
		
        private static HashMap<String, Character.UnicodeScript> aliases;
        static {
            aliases = new HashMap<>(128);
            aliases.put("ARAB", ARABIC);
            aliases.put("ZINH", INHERITED);
            aliases.put("ZYYY", COMMON);
            aliases.put("ZZZZ", UNKNOWN);
        }	
	
        public static UnicodeScript of(int codePoint) {
            if (!isValidCodePoint(codePoint))
                throw new IllegalArgumentException();
            int type = getType(codePoint);
            // leave SURROGATE and PRIVATE_USE for table lookup
            if (type == UNASSIGNED)
                return UNKNOWN;
            int index = Arrays.binarySearch(scriptStarts, codePoint);
            if (index < 0)
                index = -index - 2;
            return scripts[index];
        }
	
        public static final UnicodeScript forName(String scriptName) {
            scriptName = scriptName.toUpperCase(Locale.ENGLISH);
                                 //.replace(' ', '_'));
            UnicodeScript sc = aliases.get(scriptName);
            if (sc != null)
                return sc;
            return valueOf(scriptName);
        }
    }
	
    public static boolean isJavaIdentifierStart(char ch) {
        return isJavaIdentifierStart((int)ch);
    }	
	
    public static boolean isJavaIdentifierStart(int codePoint) {
        return CharacterData.of(codePoint).isJavaIdentifierStart(codePoint);
    }

    public static boolean isJavaIdentifierPart(char ch) {
        return isJavaIdentifierPart((int)ch);
    }
	
    public static boolean isJavaIdentifierPart(int codePoint) {
        return CharacterData.of(codePoint).isJavaIdentifierPart(codePoint);
    }
	
    public static boolean isUnicodeIdentifierStart(char ch) {
        return isUnicodeIdentifierStart((int)ch);
    }

    public static boolean isUnicodeIdentifierStart(int codePoint) {
        return CharacterData.of(codePoint).isUnicodeIdentifierStart(codePoint);
    }

    public static boolean isUnicodeIdentifierPart(char ch) {
        return isUnicodeIdentifierPart((int)ch);
    }

    public static boolean isUnicodeIdentifierPart(int codePoint) {
        return CharacterData.of(codePoint).isUnicodeIdentifierPart(codePoint);
    }

    public static boolean isIdentifierIgnorable(char ch) {
        return isIdentifierIgnorable((int)ch);
    }
    public static boolean isIdentifierIgnorable(int codePoint) {
        return CharacterData.of(codePoint).isIdentifierIgnorable(codePoint);
    }
	
    public static char toLowerCase(char ch) {
        return (char)toLowerCase((int)ch);
    }

    public static int toLowerCase(int codePoint) {
        return CharacterData.of(codePoint).toLowerCase(codePoint);
    }	

    public static char toUpperCase(char ch) {
        return (char)toUpperCase((int)ch);
    }

   public static int toUpperCase(int codePoint) {
        return CharacterData.of(codePoint).toUpperCase(codePoint);
    }	
	
    public static char toTitleCase(char ch) {
        return (char)toTitleCase((int)ch);
    }	
	
    public static int toTitleCase(int codePoint) {
        return CharacterData.of(codePoint).toTitleCase(codePoint);
    }
	
    public static int digit(char ch, int radix) {
        return digit((int)ch, radix);
    }	
	
    public static int digit(int codePoint, int radix) {
        return CharacterData.of(codePoint).digit(codePoint, radix);
    }
	
    public static int getNumericValue(char ch) {
        return getNumericValue((int)ch);
    }
	
    public static int getNumericValue(int codePoint) {
        return CharacterData.of(codePoint).getNumericValue(codePoint);
    }
	
    @Deprecated
    public static boolean isSpace(char ch) {
        return (ch <= 0x0020) &&
            (((((1L << 0x0009) |
            (1L << 0x000A) |
            (1L << 0x000C) |
            (1L << 0x000D) |
            (1L << 0x0020)) >> ch) & 1L) != 0);
    }
	
    public static boolean isSpaceChar(char ch) {
        return isSpaceChar((int)ch);
    }
	
    public static boolean isSpaceChar(int codePoint) {
        return ((((1 << Character.SPACE_SEPARATOR) |
                  (1 << Character.LINE_SEPARATOR) |
                  (1 << Character.PARAGRAPH_SEPARATOR)) >> getType(codePoint)) & 1)
            != 0;
    }
	
    public static boolean isWhitespace(char ch) {
        return isWhitespace((int)ch);
    }
	
    public static boolean isWhitespace(int codePoint) {
        return CharacterData.of(codePoint).isWhitespace(codePoint);
    }

    public static boolean isISOControl(char ch) {
        return isISOControl((int)ch);
    }
	
    public static boolean isISOControl(int codePoint) {
        // Optimized form of:
        //     (codePoint >= 0x00 && codePoint <= 0x1F) ||
        //     (codePoint >= 0x7F && codePoint <= 0x9F);
        return codePoint <= 0x9F &&
            (codePoint >= 0x7F || (codePoint >>> 5 == 0));
    }
	
    public static char forDigit(int digit, int radix) {
        if ((digit >= radix) || (digit < 0)) {
            return '\0';
        }
        if ((radix < Character.MIN_RADIX) || (radix > Character.MAX_RADIX)) {
            return '\0';
        }
        if (digit < 10) {
            return (char)('0' + digit);
        }
        return (char)('a' - 10 + digit);
    }	
	
    public static byte getDirectionality(char ch) {
        return getDirectionality((int)ch);
    }
	
    public static byte getDirectionality(int codePoint) {
        return CharacterData.of(codePoint).getDirectionality(codePoint);
    }

    public static boolean isMirrored(char ch) {
        return isMirrored((int)ch);
    }	
	
    public static boolean isMirrored(int codePoint) {
        return CharacterData.of(codePoint).isMirrored(codePoint);
    }
	
    static int toUpperCaseEx(int codePoint) {
        assert isValidCodePoint(codePoint);
        return CharacterData.of(codePoint).toUpperCaseEx(codePoint);
    }
	
    static char[] toUpperCaseCharArray(int codePoint) {
        // As of Unicode 6.0, 1:M uppercasings only happen in the BMP.
        assert isBmpCodePoint(codePoint);
        return CharacterData.of(codePoint).toUpperCaseCharArray(codePoint);
    }

    public static char reverseBytes(char ch) {
        return (char) (((ch & 0xFF00) >> 8) | (ch << 8));
    }
}
           
package java.lang;

abstract class CharacterData {
    abstract int getProperties(int ch);
    abstract int getType(int ch);
    abstract boolean isWhitespace(int ch);
    abstract boolean isMirrored(int ch);
    abstract boolean isJavaIdentifierStart(int ch);
    abstract boolean isJavaIdentifierPart(int ch);
    abstract boolean isUnicodeIdentifierStart(int ch);
    abstract boolean isUnicodeIdentifierPart(int ch);
    abstract boolean isIdentifierIgnorable(int ch);
    abstract int toLowerCase(int ch);
    abstract int toUpperCase(int ch);
    abstract int toTitleCase(int ch);
    abstract int digit(int ch, int radix);
    abstract int getNumericValue(int ch);
    abstract byte getDirectionality(int ch);

    //need to implement for JSR204
    int toUpperCaseEx(int ch) {
        return toUpperCase(ch);
    }

    char[] toUpperCaseCharArray(int ch) {
        return null;
    }

    boolean isOtherLowercase(int ch) {
        return false;
    }

    boolean isOtherUppercase(int ch) {
        return false;
    }

    boolean isOtherAlphabetic(int ch) {
        return false;
    }

    boolean isIdeographic(int ch) {
        return false;
    }

    // Character <= 0xff (basic latin) is handled by internal fast-path
    // to avoid initializing large tables.
    // Note: performance of this "fast-path" code may be sub-optimal
    // in negative cases for some accessors due to complicated ranges.
    // Should revisit after optimization of table initialization.

    static final CharacterData of(int ch) {
        if (ch >>> 8 == 0) {     // fast-path
            return CharacterDataLatin1.instance;
        } else {
            switch(ch >>> 16) {  //plane 00-16
            case(0):
                return CharacterData00.instance;
            case(1):
                return CharacterData01.instance;
            case(2):
                return CharacterData02.instance;
            case(14):
                return CharacterData0E.instance;
            case(15):   // Private Use
            case(16):   // Private Use
                return CharacterDataPrivateUse.instance;
            default:
                return CharacterDataUndefined.instance;
            }
        }
    }
}


class CharacterData00 extends CharacterData {
    int getProperties(int ch) {
        char offset = (char)ch;
        int props = A[Y[X[offset>>5]|((offset>>1)&0xF)]|(offset&0x1)];
        return props;
    }

    int getPropertiesEx(int ch) {
        char offset = (char)ch;
        int props = B[Y[X[offset>>5]|((offset>>1)&0xF)]|(offset&0x1)];
        return props;
    }

    int getType(int ch) {
        int props = getProperties(ch);
        return (props & 0x1F);
    }
	
    boolean isJavaIdentifierPart(int ch) {
        int props = getProperties(ch);
        return ((props & 0x00003000) != 0);
    }

    boolean isUnicodeIdentifierStart(int ch) {
        int props = getProperties(ch);
        return ((props & 0x00007000) == 0x00007000);
    }

    boolean isUnicodeIdentifierPart(int ch) {
        int props = getProperties(ch);
        return ((props & 0x00001000) != 0);
    }
	
    int toLowerCase(int ch) {
        int mapChar = ch;
        int val = getProperties(ch);

        if ((val & 0x00020000) != 0) {
          if ((val & 0x07FC0000) == 0x07FC0000) {
            switch(ch) {
              // map the offset overflow chars
            case 0x0130 : mapChar = 0x0069; break;
            case 0x2126 : mapChar = 0x03C9; break;
            case 0x212A : mapChar = 0x006B; break;
            case 0x212B : mapChar = 0x00E5; break;
            case 0xA78D : mapChar = 0x0265; break;
            case 0xA7AA : mapChar = 0x0266; break;
              // default mapChar is already set, so no
              // need to redo it here.
              // default       : mapChar = ch;
            }
          }
          else {
            int offset = val << 5 >> (5+18);
            mapChar = ch + offset;
          }
        }
        return mapChar;
    }	

    static {
            charMap = new char[][][] {
        { {'\u00DF'}, {'\u0053', '\u0053', } },
        { {'\u0130'}, {'\u0130', } },
        { {'\u0149'}, {'\u02BC', '\u004E', } },
        { {'\uFB13'}, {'\u0544', '\u0546', } },
        { {'\uFB14'}, {'\u0544', '\u0535', } },
        { {'\uFB15'}, {'\u0544', '\u053B', } },
        { {'\uFB16'}, {'\u054E', '\u0546', } },
        { {'\uFB17'}, {'\u0544', '\u053D', } },
    };
        { // THIS CODE WAS AUTOMATICALLY CREATED BY GenerateCharacter:
            char[] data = A_DATA.toCharArray();
            assert (data.length == (930 * 2));
            int i = 0, j = 0;
            while (i < (930 * 2)) {
                int entry = data[i++] << 16;
                A[j++] = entry | data[i++];
            }
        }

    }        
}
           
package java.lang;

/** The CharacterData class encapsulates the large tables found in
    Java.lang.Character. */

class CharacterDataPrivateUse extends CharacterData {

    int getProperties(int ch) {
        return 0;
    }

    int getType(int ch) {
	return (ch & 0xFFFE) == 0xFFFE
	    ? Character.UNASSIGNED
	    : Character.PRIVATE_USE;
    }

    boolean isJavaIdentifierStart(int ch) {
		return false;
    }

    boolean isJavaIdentifierPart(int ch) {
		return false;
    }

    boolean isUnicodeIdentifierStart(int ch) {
		return false;
    }

    boolean isUnicodeIdentifierPart(int ch) {
		return false;
    }

    boolean isIdentifierIgnorable(int ch) {
		return false;
    }

    int toLowerCase(int ch) {
		return ch;
    }

    int toUpperCase(int ch) {
		return ch;
    }

    int toTitleCase(int ch) {
		return ch;
    }

    int digit(int ch, int radix) {
		return -1;
    }

    int getNumericValue(int ch) {
		return -1;
    }

    boolean isWhitespace(int ch) {
		return false;
    }

    byte getDirectionality(int ch) {
	return (ch & 0xFFFE) == 0xFFFE
	    ? Character.DIRECTIONALITY_UNDEFINED
	    : Character.DIRECTIONALITY_LEFT_TO_RIGHT;
    }

    boolean isMirrored(int ch) {
		return false;
    }

    static final CharacterData instance = new CharacterDataPrivateUse();
    private CharacterDataPrivateUse() {};
}
           
package java.lang;

/** The CharacterData class encapsulates the large tables found in
    Java.lang.Character. */

class CharacterDataUndefined extends CharacterData {

    int getProperties(int ch) {
        return 0;
    }

    int getType(int ch) {
	return Character.UNASSIGNED;
    }

    boolean isJavaIdentifierStart(int ch) {
		return false;
    }

    boolean isJavaIdentifierPart(int ch) {
		return false;
    }

    boolean isUnicodeIdentifierStart(int ch) {
		return false;
    }

    boolean isUnicodeIdentifierPart(int ch) {
		return false;
    }

    boolean isIdentifierIgnorable(int ch) {
		return false;
    }

    int toLowerCase(int ch) {
		return ch;
    }

    int toUpperCase(int ch) {
		return ch;
    }

    int toTitleCase(int ch) {
		return ch;
    }

    int digit(int ch, int radix) {
		return -1;
    }

    int getNumericValue(int ch) {
		return -1;
    }

    boolean isWhitespace(int ch) {
		return false;
    }

    byte getDirectionality(int ch) {
		return Character.DIRECTIONALITY_UNDEFINED;
    }

    boolean isMirrored(int ch) {
		return false;
    }

    static final CharacterData instance = new CharacterDataUndefined();
    private CharacterDataUndefined() {};
}
           

繼續閱讀