jdk source code reading - Boolean, Character

Boolean

package java.lang;

/**
 * 
 */
public final class Boolean implements java.io.Serializable,
                                      Comparable<Boolean>
{
    
    public static final Boolean TRUE = new Boolean(true);

    public static final Boolean FALSE = new Boolean(false);

    /**
     * 表示基本类型 boolean 的 Class 实例
     */
    @SuppressWarnings("unchecked")
    public static final Class<Boolean> TYPE = (Class<Boolean>) Class.getPrimitiveClass("boolean");

    /**
     * Boolean的值
     */
    private final boolean value;

    private static final long serialVersionUID = -3665804199014368530L;

    public Boolean(boolean value) {
        this.value = value;
    }

    /**
     * 使用parseBoolean方法将字符串转为相应包装类型
     */
    public Boolean(String s) {
        this(parseBoolean(s));
    }

    /**
     * 不考虑字符的大小写转为相应的boolean值
     */
    public static boolean parseBoolean(String s) {
    	/**
    	 * s.equalsIgnoreCase将此 String 与另一个 String 比较,不考虑大小写
    	 */
        return ((s != null) && s.equalsIgnoreCase("true"));
    }

    /**
     * 返回Boolean的value值为基础类型
     */
    public boolean booleanValue() {
        return value;
    }

    /**
     * 根据基础类型boolean实例一个值相等的包装类型
     */
    public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }

    /**
     * 根据字符串的值转为值相等的相应的包装类型
     */
    public static Boolean valueOf(String s) {
        return parseBoolean(s) ? TRUE : FALSE;
    }

    /**
     * 将基础类型转为相应字符串
     */
    public static String toString(boolean b) {
        return b ? "true" : "false";
    }

    /**
     * 将包装类型的值转为相应的字符串
     */
    public String toString() {
        return value ? "true" : "false";
    }

    /**
     * Boolean的hash方法,为其值的hash方法返回的值
     */
    @Override
    public int hashCode() {
        return Boolean.hashCode(value);
    }

    /**
     * 当为true时hash值为1231,为false时 为1237
     */
    public static int hashCode(boolean value) {
        return value ? 1231 : 1237;
    }

   /**
     * 当一个对象是Boolean类型,且和本对象的值value相等时,这两个Boolean类型相等
     */
    public boolean equals(Object obj) {
        if (obj instanceof Boolean) {
            return value == ((Boolean)obj).booleanValue();
        }
        return false;
    }

    /**
     * 当且仅当以参数命名的系统属性存在,且等于 "true" 字符串时,才返回 true。
     */
    public static boolean getBoolean(String name) {
        boolean result = false;
        try {
            result = parseBoolean(System.getProperty(name));//System.getProperty(name)获取当前系统的某些属性
        } catch (IllegalArgumentException | NullPointerException e) {
        }
        return result;
    }

    /**
     * 比较两个Boolean对象
     */
    public int compareTo(Boolean b) {
        return compare(this.value, b.value);
    }

    /**
     * 比较两个booelan值,如果两个同为真或者同为假返回0,第一个为真,第二个为假返回1,第一个为假,第二个为真返回-1
     */
    public static int compare(boolean x, boolean y) {
        return (x == y) ? 0 : (x ? 1 : -1);
    }

    /**
     * 返回两个boolean值的逻辑与
     */
    public static boolean logicalAnd(boolean a, boolean b) {
        return a && b;
    }

    /**
     * 返回两个boolean值的逻辑或
     */
    public static boolean logicalOr(boolean a, boolean b) {
        return a || b;
    }

    /**
     * 返回两个boolean值的异或值,即两个boolean值同为真或同为假返回假,当他们的值不同时返回真
     */
    public static boolean logicalXor(boolean a, boolean b) {
        return a ^ b;
    }
    
    
}

 

Character


package java.lang;

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

/**
 * java.io.Serializable序列化接口,表明这个类可以序列化,如果某些字段不想序列化可以使用关键字transient
 * Comparable比较接口,需要实现compareTo方法
 * 
 * 
 * 1、Unicode编码基本概念
 * (1)编码字符集
 * 		编码字符集是一个字符集,它为每一个字符分配一个唯一数字。
 * 
 * 		Unicode 标准的核心是一个编码字符集,字母“A”的编码为0041和字符“€”的编码为20AC。
 * 		Unicode标准始终使用十六进制数字,而且在书写时在前面加上前缀“U+”,所以“A”的编码书写为“U+0041”。
 * (2)代码点codepoint和代码单元
 * 		代码点是指可用于编码字符集的数字。编码字符集定义一个有效的代码点范围,但是并不一定将字符分配给所有这些代码点。
 * 		有效的 Unicode代码点范围是 U+0000 至 U+10FFFF
 * 
 * 		代码单元可以理解为字符编码的一个基本单元,最常用的代码单元是字节(即8位),但是16位和32位整数也可以用于内部处理。
 * (3)增补字符
 * 		16 位编码的所有 65536 个字符并不能完全表示全世界所有正在使用或曾经使用的字符。
 * 		于是,Unicode 标准已扩展到包含多达 1112064 个字符。那些超出原来的16 位限制的字符被称作增补字符。
 * 
 * 		Java的char类型是固定16bits的。代码点在U+0000 — U+FFFF之内到是可以用一个char完整的表示出一个字符。
 * 		但代码点在U+FFFF之外的,一个char无论如何无法表示一个完整字符。这样用char类型来获取字符串中的那些代码点在U+FFFF之外的字符就会出现问题。
 * 
 * 		因此,Java 平台不仅需要支持增补字符,而且必须使应用程序能够方便地做到这一点。
 * 		Java Community Process 召集了一个专家组,以期找到一个适当的解决方案。
 * 		该小组被称为JSR-204专家组,使用Unicode 增补字符支持的Java技术规范请求的编号。
 * 
 * 		增补字符是代码点在 U+10000 至 U+10FFFF(因为从1到10在二进制表现上来看为0001到1010因此实际上二进制上只需要增加4位即可) 范围之间的字符,
 * 		也就是那些使用原始的 Unicode 的 16 位设计无法表示的字符。
 * 		从 U+0000 至 U+FFFF 之间的字符集有时候被称为基本多语言面 (BMP UBasic Multilingual Plane )。
 * 		因此,每一个 Unicode 字符要么属于 BMP,要么属于增补字符。
 * 
 * 2、基于Unicode的具体编码格式
 * 		UTF-32: 即将每一个 Unicode 代码点表示为相同值的32位整数。很明显,它是内部处理最方便的表达方式,
 * 		但是,如果作为一般字符串表达方式,则要消耗更多的内存。
 * 
 * 		UTF-16: 使用一个或两个未分配的16位代码单元的序列对 Unicode 代码点进行编码。(高代理和低代理是相对utf-16说的其余两个是不存在这种说法的)
 * 		假设U是一个代码点,也就是Unicode编码表中一个字符所对应的Unicode值。
 * 			(1) 如果在BMP级别中,那么16bits(一个代码单元)就足够表示出字符的Unicode值。在基本平面内,从 U+D800 到 U+DFFF 是一个空段,即这些码点不对应任何字符。
 * 			(2) 如果U+10FFFF>U>=U+10000,也就是处于增补字符级别中。UTF-16用2个16位来表示出了,
 * 				并且正好将每个16位都控制在替代区域U+D800-U+DFFF其中\uD800-\uDBFF为高代理项 范围,\uDC00-  \uDFFF为低代理项 范围) 中。
 * 				【因为D的二进制表示为1101,而8到B的二进制的前两位一直为10,因此高代理项的二进制的开头6位一定为110110】
 * 				【与上面同样的道理,C到F的二进制的前两位一直为11,因此低代理项的二进制的开头6位一定为110111】
 * 
 * 		下面来看一下Java是如何处理这些增补字符的。  
 * 		分别初始化2个16位无符号的整数 —— W1和W2。其中W1=110110yyyyyyyyyy(0xD800-0xDBFF),W2 = 110111xxxxxxxxxx(0xDC00-OxDFFF)。
 * 		然后,将Unicode的高10位分配给W1的低10位,将Unicode 的低10位分配给W2的低10位。并加上(0001 0000 0000 0000 0000)
 * 		(因为增补字符只需要增加4位加上原来的16位,所以一共20位,且增补字符的Unicode值从U+10000开始)
 * 		这样就可以将20bits的代码点U拆成两个16bits的代码单元。而且这两个代码点正好落在替代区域U+D800-U+DFFF中。
 * 
 * 		举个例子:代码点U+1D56B(使用4个字节表示的代码点)
 * 		0x1D56B= 0001 1101 01  01 0110 1011
 * 		然后减去(0001 0000 0000 0000 0000)得0000 1101 01  01 0110 1011
 * 		将0x1D56B的高10位0000 1101 01分配给W1的低10位组合成110110(高代理) 0000 1101 01=0xD835
 * 		将0x1D56B的低10位01 0110 1011分配给W2的低10位组合成110111(低代理) 01 0110 1011=0xDD6B
 * 		这样代码点U+1D56B采用UTF-16编码方式,用2个连续的代码单元U+D875和U+DD68表示出了。于是降低了存储的内存
 * 
 * 
 * 		UTF-8: 是目前互联网上使用最广泛的一种 Unicode 编码方式,它的最大特点就是可变长。
 * 		它可以使用 1 - 4 个字节表示一个字符,根据字符的不同变换长度。编码规则如下:
 * 		
 * 		1、对于单个字节的字符,第一位设为 0,后面的 7 位对应这个字符的 Unicode 码点。因此,对于英文中的 0 - 127 号字符,与 ASCII 码完全相同。
 * 		这意味着 ASCII 码编写的文档用 UTF-8 编码打开完全没有问题。
 * 		2、对于需要使用 N 个字节来表示的字符(N > 1),第一个字节的前 N 位都设为 1,第 N + 1 位设为0,剩余的 N - 1 个字节的前两位都设位 10,
 * 		剩下的二进制位则使用这个字符的 Unicode 码点来填充。
 * 		即:
 * 		Unicode 十六进制码点范围					UTF-8 二进制
 * 		0000 0000 - 0000 007F				0xxxxxxx
 * 		0000 0080 - 0000 07FF				110xxxxx 10xxxxxx
 * 		0000 0800 - 0000 FFFF				1110xxxx 10xxxxxx 10xxxxxx
 * 		0001 0000 - 0010 FFFF				11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
 * 		
 * 		下面以汉字“汉”为利,具体说明如何进行 UTF-8 编码和解码。
 * 		“汉”的 Unicode 码点是 0x6c49(110 1100 0100 1001),通过上面的对照表可以发现,0x0000 6c49 位于第三行的范围,
 * 		那么得出其格式为 1110xxxx 10xxxxxx 10xxxxxx。接着,从“汉”的二进制数最后一位开始,从后向前依次填充对应格式中的 x,多出的 x 用 0 补上。
 * 		这样,就得到了“汉”的 UTF-8 编码为 11100110 10110001 10001001,转换成十六进制就是 0xE6 0xB7 0x89。
 * 		解码的过程也十分简单:如果一个字节的第一位是 0 ,则说明这个字节对应一个字符;如果一个字节的第一位1,那么连续有多少个 1,就表示该字符占用多少个字节。
 * 
 */
public final
class Character implements java.io.Serializable, Comparable<Character> {
    /**
     * 可用于与字符串相互转换的最小基数。
     */
    public static final int MIN_RADIX = 2;

    /**
     * 可用于与字符串相互转换的最大基数。
     */
    public static final int MAX_RADIX = 36;

    /**
     * char类型的最小值(0)
     */
    public static final char MIN_VALUE = '\u0000';

    /**
     * char类型的最大值(65535)——1111111111111111
     */
    public static final char MAX_VALUE = '\uFFFF';

    /**
     * 表示基本类型 char 的 Class 实例
     */
    @SuppressWarnings("unchecked")
    public static final Class<Character> TYPE = (Class<Character>) Class.getPrimitiveClass("char");

    

    /**
     * UTF-16 编码中的 Unicode 高代理项代码单元的最小值。55296——1101100000000000
     */
    public static final char MIN_HIGH_SURROGATE = '\uD800';

    /**
     * UTF-16 编码中的 Unicode 高代理项代码单元的最大值。56319——1101101111111111
     */
    public static final char MAX_HIGH_SURROGATE = '\uDBFF';

    /**
     * UTF-16 编码中的 Unicode 低代理项代码单元的最小值。56320——1101110000000000
     */
    public static final char MIN_LOW_SURROGATE  = '\uDC00';

    /**
     * UTF-16 编码中的 Unicode 低代理项代码单元的最大值。57343——1101111111111111
     */
    public static final char MAX_LOW_SURROGATE  = '\uDFFF';

    /**
     *  UTF-16 编码中的 Unicode 代理项代码单元的最小值。
     */
    public static final char MIN_SURROGATE = MIN_HIGH_SURROGATE;

    /**
     * UTF-16 编码中的 Unicode 代理项代码单元的最大值。
     */
    public static final char MAX_SURROGATE = MAX_LOW_SURROGATE;

    /**
     * 增补代码点的最小值。65536——10000000000000000;0x代表16进制
     */
    public static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000;

    /**
     * Unicode 代码点的最小值。0
     */
    public static final int MIN_CODE_POINT = 0x000000;

    /**
     * Unicode 代码点的最大值。1114111——100001111111111111111
     */
    public static final int MAX_CODE_POINT = 0X10FFFF;


    

    /**
     * Character的值
     */
    private final char value;

    private static final long serialVersionUID = 3786198910865385080L;

    /**
     * 
     */
    public Character(char value) {
        this.value = value;
    }

    /**
     * 将ascii的128个字符缓存起来
     *
     */
    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);
        }
    }

    /**
     * 根据char类型返回相应的Character对象
     */
    public static Character valueOf(char c) {
        if (c <= 127) { // must cache
        	//转为int,根据序号从CharacterCache中的静态数组取出相应的Character
            return CharacterCache.cache[(int)c];
        }
        return new Character(c);
    }

    /**
     * 返回Character的值value
     */
    public char charValue() {
        return value;
    }

    /**
     * 返回Character的hash值
     */
    @Override
    public int hashCode() {
        return Character.hashCode(value);
    }

    /**
     * 返回基础类型的hash值,值为其对应的Unicode值
     */
    public static int hashCode(char value) {
        return (int)value;
    }

    /**
     * 如果两个对象均为Character,且值相等,则这两个对象相等
     */
    public boolean equals(Object obj) {
        if (obj instanceof Character) {
            return value == ((Character)obj).charValue();
        }
        return false;
    }

    /**
     * 将Character转为string
     */
    public String toString() {
        char buf[] = {value};
        return String.valueOf(buf);
    }

    /**
     * 将char转为string
     */
    public static String toString(char c) {
        return String.valueOf(c);
    }

    /**
     * 确定指定的代码点是否为从 0x0000 到 0x10FFFF 范围之内的有效 Unicode值。
     */
    public static boolean isValidCodePoint(int codePoint) {
        int plane = codePoint >>> 16;
        return plane < ((MAX_CODE_POINT + 1) >>> 16);
    }

    /**
     * 判断一个Unicode值是不是BMP字符
     */
    public static boolean isBmpCodePoint(int codePoint) {
        return codePoint >>> 16 == 0;
    }

    /**
     * 确定Unicode值是否在增补字符范围内。
     */
    public static boolean isSupplementaryCodePoint(int codePoint) {
        return codePoint >= MIN_SUPPLEMENTARY_CODE_POINT
            && codePoint <  MAX_CODE_POINT + 1;
    }

    /**
     * 确定给出的 char 值是否为一个高代理项代码单元
     */
    public static boolean isHighSurrogate(char ch) {
        return ch >= MIN_HIGH_SURROGATE && ch < (MAX_HIGH_SURROGATE + 1);
    }

    /**
     * 确定给定 char 值是否一个低代理项代码单元
     */
    public static boolean isLowSurrogate(char ch) {
        return ch >= MIN_LOW_SURROGATE && ch < (MAX_LOW_SURROGATE + 1);
    }

    /**
     * 确定给定 char 值是否是代理项代码单元。
     */
    public static boolean isSurrogate(char ch) {
        return ch >= MIN_SURROGATE && ch < (MAX_SURROGATE + 1);
    }

    /**
     * 确定指定的 char 值对是否为有效的代理项对。
     */
    public static boolean isSurrogatePair(char high, char low) {
        return isHighSurrogate(high) && isLowSurrogate(low);
    }

    /**
     * 确定表示Unicode值所代表的字符所需的 char 值的数量。
     */
    public static int charCount(int codePoint) {
        return codePoint >= MIN_SUPPLEMENTARY_CODE_POINT ? 2 : 1;
    }

    /**
     * 将指定的代理项对转换为其增补代码点值。但是这个方法没有验证这个代理项对是否合法,
     * 如有必要需要调用方法isSurrogatePair自行验证
     */
    public static int toCodePoint(char high, char low) {
        return ((high << 10) + low) + (MIN_SUPPLEMENTARY_CODE_POINT
                                       - (MIN_HIGH_SURROGATE << 10)
                                       - MIN_LOW_SURROGATE);
    }

    /**
     * 返回 CharSequence 的给定索引上的char的Unicode值。
     * 其中如果 CharSequence 中的给定索引上的 char 值在高代理项范围内,且index的下一个索引没有超出范围,则返回对应于此代理项对的增补代码点。
     * 否则,返回给定索引上的 char对应的Unicode值,如果给定索引在低代理项范围内也返回char对应的Unicode值而不是返回代理项对的增补代码点。 
     */
    public static int codePointAt(CharSequence seq, int index) {
        char c1 = seq.charAt(index);
        if (isHighSurrogate(c1) && ++index < seq.length()) {
            char c2 = seq.charAt(index);
            if (isLowSurrogate(c2)) {
                return toCodePoint(c1, c2);
            }
        }
        return c1;
    }

    /**
     * 返回 数组a 的给定索引上的char的Unicode值。
     * 其中如果 数组a 中的给定索引上的 char 值在高代理项范围内,且index的下一个索引没有超出范围,而且下一个索引的char值在低代理项范围内,则返回对应于此代理项对的增补代码点。
     * 否则,返回给定索引上的 char对应的Unicode值,如果给定索引在低代理项范围内也返回char对应的Unicode值而不是返回代理项对的增补代码点。
     */
    public static int codePointAt(char[] a, int index) {
        return codePointAtImpl(a, index, a.length);
    }

    /**
     * 返回 数组a 的给定索引上的char的Unicode值。
     * 其中如果 数组a 中的给定索引上的 char 值在高代理项范围内,且index的下一个索引没有超出范围,而且下一个索引的char值在低代理项范围内,则返回对应于此代理项对的增补代码点。
     * 否则,返回给定索引上的 char对应的Unicode值,如果给定索引在低代理项范围内也返回char对应的Unicode值而不是返回代理项对的增补代码点。
     * 其中只能使用a[0]到a[limit]的元素可以使用
     */
    public static int codePointAt(char[] a, int index, int limit) {
        if (index >= limit || limit < 0 || limit > a.length) {
            throw new IndexOutOfBoundsException();
        }
        return codePointAtImpl(a, index, limit);
    }

    // 会抛出各种超出数组范围的异常
    static int codePointAtImpl(char[] a, int index, int limit) {
        char c1 = a[index];
        if (isHighSurrogate(c1) && ++index < limit) {
            char c2 = a[index];
            if (isLowSurrogate(c2)) {
                return toCodePoint(c1, c2);
            }
        }
        return c1;
    }

    /**
     * 返回 数组a 的给定索引上的char的Unicode值。
     * 其中如果 数组a 中的给定索引上的 char 值在低代理项范围内,且index的前一个索引没有超出范围,而且前一个索引的char值在高代理项范围内,则返回对应于此代理项对的增补代码点。
     * 否则,返回给定索引上的 char对应的Unicode值,如果给定索引在高代理项范围内也返回char对应的Unicode值而不是返回代理项对的增补代码点。
     */
    public static int codePointBefore(CharSequence seq, int index) {
        char c2 = seq.charAt(--index);
        if (isLowSurrogate(c2) && index > 0) {
            char c1 = seq.charAt(--index);
            if (isHighSurrogate(c1)) {
                return toCodePoint(c1, c2);
            }
        }
        return c2;
    }

    /**
     * 返回 数组a 的给定索引上的char的Unicode值。
     * 其中如果 数组a 中的给定索引上的 char 值在低代理项范围内,且index的前一个索引没有超出范围,而且前一个索引的char值在高代理项范围内,则返回对应于此代理项对的增补代码点。
     * 否则,返回给定索引上的 char对应的Unicode值,如果给定索引在高代理项范围内也返回char对应的Unicode值而不是返回代理项对的增补代码点。
     */
    public static int codePointBefore(char[] a, int index) {
        return codePointBeforeImpl(a, index, 0);
    }

    /**
     * 返回 数组a 的给定索引上的char的Unicode值。
     * 其中如果 数组a 中的给定索引上的 char 值在低代理项范围内,且index的前一个索引没有超出范围,而且前一个索引的char值在高代理项范围内,则返回对应于此代理项对的增补代码点。
     * 否则,返回给定索引上的 char对应的Unicode值,如果给定索引在高代理项范围内也返回char对应的Unicode值而不是返回代理项对的增补代码点。
     * 其中只能使用a[start]到a[length-1]的元素可以使用
     */
    public static int codePointBefore(char[] a, int index, int start) {
        if (index <= start || start < 0 || start >= a.length) {
            throw new IndexOutOfBoundsException();
        }
        return codePointBeforeImpl(a, index, start);
    }

    // 会抛出各种超出数组范围的异常
    static int codePointBeforeImpl(char[] a, int index, int start) {
        char c2 = a[--index];
        if (isLowSurrogate(c2) && index > start) {
            char c1 = a[--index];
            if (isHighSurrogate(c1)) {
                return toCodePoint(c1, c2);
            }
        }
        return c2;
    }

    /**
     * 如果unicode代码点是增补代码点则返回其高代理项的char值,否则返回的值不确定
     */
    public static char highSurrogate(int codePoint) {
        return (char) ((codePoint >>> 10)
            + (MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT >>> 10)));
    }

    /**
     * 如果unicode代码点是增补代码点则返回其低代理项的char值,否则返回的值不确定
     */
    public static char lowSurrogate(int codePoint) {
        return (char) ((codePoint & 0x3ff) + MIN_LOW_SURROGATE);
    }

    /**
     * 如果指定代码点是一个 BMP值,则在 dst[dstIndex] 中存储其char值,并返回 1。
     * 如果指定代码点是一个增补字符,则将其高代理项的char值存储在 dst[dstIndex]且低代理项存储在 dst[dstIndex+1]中,并返回 2。 
     */
    public static int toChars(int codePoint, char[] dst, int dstIndex) {
        if (isBmpCodePoint(codePoint)) {
            dst[dstIndex] = (char) codePoint;
            return 1;
        } else if (isValidCodePoint(codePoint)) {
            toSurrogates(codePoint, dst, dstIndex);
            return 2;
        } else {
            throw new IllegalArgumentException();
        }
    }

    /**
     * 果指定的代码点是一个 BMP值,则得到的 char数组只有一个元素即unicode代码点的char值。
     * 如果指定的代码点是一个增补代码点,则得到的 char 数组为unicode代码点对应的代理项对。高代理在前,低代理在后
     */
    public static char[] toChars(int codePoint) {
        if (isBmpCodePoint(codePoint)) {
            return new char[] { (char) codePoint };
        } else if (isValidCodePoint(codePoint)) {
            char[] result = new char[2];
            toSurrogates(codePoint, result, 0);
            return result;
        } else {
            throw new IllegalArgumentException();
        }
    }
    
    static void toSurrogates(int codePoint, char[] dst, int index) {
        dst[index+1] = lowSurrogate(codePoint);
        dst[index] = highSurrogate(codePoint);
    }

    /**
     * 返回seq中从beginIndex到endIndex-1中unicode代码点数目
     * 如果是成对的代理项对视为1个,如果不是成对的视为2个
     */
    public static int codePointCount(CharSequence seq, int beginIndex, int endIndex) {
        int length = seq.length();
        if (beginIndex < 0 || endIndex > length || beginIndex > endIndex) {
            throw new IndexOutOfBoundsException();
        }
        int n = endIndex - beginIndex;
        for (int i = beginIndex; i < endIndex; ) {
            if (isHighSurrogate(seq.charAt(i++)) && i < endIndex &&
                isLowSurrogate(seq.charAt(i))) {
                n--;
                i++;
            }
        }
        return n;
    }

    /**
     * 返回数组a中从beginIndex到endIndex-1中unicode代码点数目
     * 如果是成对的代理项对视为1个,如果不是成对的视为2个
     */
    public static int codePointCount(char[] a, int offset, int count) {
        if (count > a.length - offset || offset < 0 || count < 0) {
            throw new IndexOutOfBoundsException();
        }
        return codePointCountImpl(a, offset, count);
    }
    
    /**
     * 判断char数组中从offset开始的共计count个char中Unicode 代码点数量。
     */
    static int codePointCountImpl(char[] a, int offset, int count) {
        int endIndex = offset + count;
        int n = count;
        for (int i = offset; i < endIndex; ) {
            if (isHighSurrogate(a[i++]) && i < endIndex &&
                isLowSurrogate(a[i])) {
                n--;
                i++;
            }
        }
        return n;
    }

    /**
     * 返回给定字符序列seq中的索引偏移量,它是从给定 index 到 codePointOffset 代码点的偏移量。
     * index 和 codePointOffset 给出的文本范围内的成对的代理项对视为1个,如果不是成对的视为2个
     */
    public static int offsetByCodePoints(CharSequence seq, int index,
                                         int codePointOffset) {
        int length = seq.length();
        if (index < 0 || index > length) {
            throw new IndexOutOfBoundsException();
        }

        int x = index;
        if (codePointOffset >= 0) {
            int i;
            for (i = 0; x < length && i < codePointOffset; i++) {
                if (isHighSurrogate(seq.charAt(x++)) && x < length &&
                    isLowSurrogate(seq.charAt(x))) {
                    x++;
                }
            }
            if (i < codePointOffset) {
                throw new IndexOutOfBoundsException();
            }
        } else {
            int i;
            for (i = codePointOffset; x > 0 && i < 0; i++) {
                if (isLowSurrogate(seq.charAt(--x)) && x > 0 &&
                    isHighSurrogate(seq.charAt(x-1))) {
                    x--;
                }
            }
            if (i < 0) {
                throw new IndexOutOfBoundsException();
            }
        }
        return x;
    }

    /**
     * 返回给定字符序列seq中的索引偏移量,它是从给定 index 到 codePointOffset 代码点的偏移量。
     * 其中index和要寻找的codePointOffset代码点必须在数组的a[start]到a[start+count]范围内,另外start+count不能大于length
     * 
     * index 和 codePointOffset 给出的文本范围内的成对的代理项对视为1个,如果不是成对的视为2个
     */
    public static int offsetByCodePoints(char[] a, int start, int count,
                                         int index, int codePointOffset) {
        if (count > a.length-start || start < 0 || count < 0
            || index < start || index > start+count) {
            throw new IndexOutOfBoundsException();
        }
        return offsetByCodePointsImpl(a, start, count, index, codePointOffset);
    }

    /**
     * 功能与offsetByCodePoints(CharSequence seq, int index,int codePointOffset)一样,
     * 只不过多加了一个判断的范围
     */
    static int offsetByCodePointsImpl(char[]a, int start, int count,
                                      int index, int codePointOffset) {
        int x = index;
        if (codePointOffset >= 0) {
            int limit = start + count;
            int i;
            for (i = 0; x < limit && i < codePointOffset; i++) {
                if (isHighSurrogate(a[x++]) && x < limit &&
                    isLowSurrogate(a[x])) {
                    x++;
                }
            }
            if (i < codePointOffset) {
                throw new IndexOutOfBoundsException();
            }
        } else {
            int i;
            for (i = codePointOffset; x > start && i < 0; i++) {
                if (isLowSurrogate(a[--x]) && x > start &&
                    isHighSurrogate(a[x-1])) {
                    x--;
                }
            }
            if (i < 0) {
                throw new IndexOutOfBoundsException();
            }
        }
        return x;
    }

    /**
     * 确定指定字符是否为小写字母。
     * 此方法无法处理增补字符。若要支持所有 Unicode 字符,包括增补字符,请使用 isLowerCase(int) 方法。
     */
    public static boolean isLowerCase(char ch) {
        return isLowerCase((int)ch);
    }

    /**
     * 确定Unicode 代码点是否为小写字母。
     */
    public static boolean isLowerCase(int codePoint) {
        return getType(codePoint) == Character.LOWERCASE_LETTER ||
               CharacterData.of(codePoint).isOtherLowercase(codePoint);
    }

    /**
     * 确定指定字符是否为大写字母。 
     * 此方法无法处理增补字符。若要支持所有 Unicode 字符,包括增补字符,请使用 isUpperCase(int) 方法。
     */
    public static boolean isUpperCase(char ch) {
        return isUpperCase((int)ch);
    }

    /**
     * 确定Unicode 代码点是否为大写字母。
     */
    public static boolean isUpperCase(int codePoint) {
        return getType(codePoint) == Character.UPPERCASE_LETTER ||
               CharacterData.of(codePoint).isOtherUppercase(codePoint);
    }

    /**
     * 确定指定字符是否为首字母大写字符。
     * 此方法无法处理增补字符。若要支持所有 Unicode 字符,包括增补字符,请使用 isTitleCase(int) 方法。
     */
    public static boolean isTitleCase(char ch) {
        return isTitleCase((int)ch);
    }

    /**
     * 确定Unicode 代码点是否为首字母大写字符。
     */
    public static boolean isTitleCase(int codePoint) {
        return getType(codePoint) == Character.TITLECASE_LETTER;
    }

    /**
     * 确定指定字符是否为数字。
     * 此方法无法处理增补字符。若要支持所有 Unicode 字符,包括增补字符,请使用 isDigit(int) 方法。
     */
    public static boolean isDigit(char ch) {
        return isDigit((int)ch);
    }

    /**
     * 确定Unicode 代码点是否为数字。
     */
    public static boolean isDigit(int codePoint) {
        return getType(codePoint) == Character.DECIMAL_DIGIT_NUMBER;
    }

    /**
     * 确定字符是否被定义为 Unicode 中的字符。
     * 此方法无法处理增补字符。若要支持所有 Unicode 字符,包括增补字符,请使用 isDefined(int) 方法。
     */
    public static boolean isDefined(char ch) {
        return isDefined((int)ch);
    }

    /**
     * 确定Unicode 代码点是否被定义为 Unicode 中的字符。
     */
    public static boolean isDefined(int codePoint) {
        return getType(codePoint) != Character.UNASSIGNED;
    }

    /**
     * 确定指定字符是否为字母。
     * 此方法无法处理增补字符。若要支持所有 Unicode 字符,包括增补字符,请使用 isLetter(int) 方法。 
     */
    public static boolean isLetter(char ch) {
        return isLetter((int)ch);
    }

    /**
     * 确定指定Unicode 代码点是否为字母。
     */
    public static boolean isLetter(int codePoint) {
        return ((((1 << Character.UPPERCASE_LETTER) |
            (1 << Character.LOWERCASE_LETTER) |
            (1 << Character.TITLECASE_LETTER) |
            (1 << Character.MODIFIER_LETTER) |
            (1 << Character.OTHER_LETTER)) >> getType(codePoint)) & 1)
            != 0;
    }

    /**
     * 确定指定字符是否为字母或数字。
     * 此方法无法处理增补字符。若要支持所有 Unicode 字符,包括增补字符,请使用 isLetterOrDigit(int) 方法。 

     */
    public static boolean isLetterOrDigit(char ch) {
        return isLetterOrDigit((int)ch);
    }

    /**
     * 确定Unicode 代码点是否为字母或数字。
     */
    public static boolean isLetterOrDigit(int codePoint) {
        return ((((1 << Character.UPPERCASE_LETTER) |
            (1 << Character.LOWERCASE_LETTER) |
            (1 << Character.TITLECASE_LETTER) |
            (1 << Character.MODIFIER_LETTER) |
            (1 << Character.OTHER_LETTER) |
            (1 << Character.DECIMAL_DIGIT_NUMBER)) >> getType(codePoint)) & 1)
            != 0;
    }

    /**
     * 
     */
    @Deprecated
    public static boolean isJavaLetter(char ch) {
        return isJavaIdentifierStart(ch);
    }

    /**
     * 
     */
    @Deprecated
    public static boolean isJavaLetterOrDigit(char ch) {
        return isJavaIdentifierPart(ch);
    }

    /**
     * 确定指定的Unicode代码点是否是字母
     */
    public static boolean isAlphabetic(int codePoint) {
        return (((((1 << Character.UPPERCASE_LETTER) |
            (1 << Character.LOWERCASE_LETTER) |
            (1 << Character.TITLECASE_LETTER) |
            (1 << Character.MODIFIER_LETTER) |
            (1 << Character.OTHER_LETTER) |
            (1 << Character.LETTER_NUMBER)) >> getType(codePoint)) & 1) != 0) ||
            CharacterData.of(codePoint).isOtherAlphabetic(codePoint);
    }

    /**
     * 确定指定Unicode代码点是否是Unicode标准定义的CJKV(中文,日文,韩文和越南文)表意文字。 
     */
    public static boolean isIdeographic(int codePoint) {
        return CharacterData.of(codePoint).isIdeographic(codePoint);
    }

    /**
     * 通过数据类CharacterData的方法确定指定字符是否允许作为Java标识符中的第一个字符。
     * 标识符:就是用于Java程序中变量,类,方法等命名的符号。
     */
    public static boolean isJavaIdentifierStart(char ch) {
        return isJavaIdentifierStart((int)ch);
    }

    /**
     * 确定Unicode代码点是否允许作为Java标识符中的第一个字符。 
     */
    public static boolean isJavaIdentifierStart(int codePoint) {
        return CharacterData.of(codePoint).isJavaIdentifierStart(codePoint);
    }

    /**
     * 确定指定的字符是否可以是Java标识符首字符以外的部分
     */
    public static boolean isJavaIdentifierPart(char ch) {
        return isJavaIdentifierPart((int)ch);
    }

    /**
     * 确定Unicode代码点是否可以是Java标识符首字符以外的部分 
     */
    public static boolean isJavaIdentifierPart(int codePoint) {
        return CharacterData.of(codePoint).isJavaIdentifierPart(codePoint);
    }

    /**
     * 确定是否允许将指定字符作为 Unicode 标识符中的首字符。
     */
    public static boolean isUnicodeIdentifierStart(char ch) {
        return isUnicodeIdentifierStart((int)ch);
    }

    /**
     *  确定是否允许将指定Unicode 代码点作为 Unicode 标识符中的首字符。
     */
    public static boolean isUnicodeIdentifierStart(int codePoint) {
        return CharacterData.of(codePoint).isUnicodeIdentifierStart(codePoint);
    }

    /**
     * 确定指定字符是否可以是 Unicode 标识符中首字符以外的部分。
     */
    public static boolean isUnicodeIdentifierPart(char ch) {
        return isUnicodeIdentifierPart((int)ch);
    }

    /**
     * 确定指定Unicode 代码点是否可以是 Unicode 标识符中首字符以外的部分。
     */
    public static boolean isUnicodeIdentifierPart(int codePoint) {
        return CharacterData.of(codePoint).isUnicodeIdentifierPart(codePoint);
    }

    /**
     * 确定是否应该认为指定字符是 Java 标识符或 Unicode 标识符中可忽略的一个字符。
     */
    public static boolean isIdentifierIgnorable(char ch) {
        return isIdentifierIgnorable((int)ch);
    }

    /**
     * 确定是否应该认为指定Unicode 代码点是 Java 标识符或 Unicode 标识符中可忽略的一个字符。
     */
    public static boolean isIdentifierIgnorable(int codePoint) {
        return CharacterData.of(codePoint).isIdentifierIgnorable(codePoint);
    }

    /**
     * 将字符转换为小写。
     */
    public static char toLowerCase(char ch) {
        return (char)toLowerCase((int)ch);
    }

    /**
     * 将Unicode 代码点转换为小写。
     */
    public static int toLowerCase(int codePoint) {
        return CharacterData.of(codePoint).toLowerCase(codePoint);
    }

    /**
     * 将字符转换为大写。
     */
    public static char toUpperCase(char ch) {
        return (char)toUpperCase((int)ch);
    }

    /**
     * 将Unicode 代码点转换为大写。
     */
    public static int toUpperCase(int codePoint) {
        return CharacterData.of(codePoint).toUpperCase(codePoint);
    }

    /**
     * 将字符转换为首字母大写。
     */
    public static char toTitleCase(char ch) {
        return (char)toTitleCase((int)ch);
    }

    /**
     * 将Unicode 代码点转换为首字母大写。
     */
    public static int toTitleCase(int codePoint) {
        return CharacterData.of(codePoint).toTitleCase(codePoint);
    }

    /**
     * 返回字符ch在进制radix中所代表的值,
     * 例如:字符'a'在16进制中代表10,字符'f'在16进制中代表15
     */
    public static int digit(char ch, int radix) {
        return digit((int)ch, radix);
    }

    /**
     * 返回unicode代码点在进制radix中所代表的值,
     * 例如:字符'a'在16进制中代表10,字符'f'在16进制中代表15
     */
    public static int digit(int codePoint, int radix) {
        return CharacterData.of(codePoint).digit(codePoint, radix);
    }

    /**
     * 返回指定的字符表示的值。
     * 功用与digit方法差不多,其中radix=ch的值,不同的是,这里有可能使用的罗马字符的50之类的字符,这时候返回50
     */
    public static int getNumericValue(char ch) {
        return getNumericValue((int)ch);
    }

    /**
     * 返回指定的Unicode 代码点表示的值。
     * 功用与digit方法差不多,其中radix=ch的值,不同的是,这里有可能使用的罗马字符的50之类的字符,这时候返回50
     */
    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);
    }


    /**
     * 确定指定字符是否为 Unicode 空白字符。当且仅当根据 Unicode 标准将字符指定为空白字符时,才认为字符是一个空白字符。
     * 如果字符的常规类别的类型为以下类型中的任意一种,则该方法返回 true: 
     * Character.SPACE_SEPARATOR 
     * Character.LINE_SEPARATOR 
     * Character.PARAGRAPH_SEPARATOR 
     * 但是经测试并无效果
     */
    public static boolean isSpaceChar(char ch) {
        return isSpaceChar((int)ch);
    }

    /**
     * 确定指定Unicode 代码点是否为 Unicode 空白字符。当且仅当根据 Unicode 标准将字符指定为空白字符时,才认为字符是一个空白字符。
     * 如果字符的常规类别的类型为以下类型中的任意一种,则该方法返回 true: 
     * Character.SPACE_SEPARATOR 
     * Character.LINE_SEPARATOR 
     * Character.PARAGRAPH_SEPARATOR 
     * 但是经测试并无效果,只有为空格时返回true
     */
    public static boolean isSpaceChar(int codePoint) {
        return ((((1 << Character.SPACE_SEPARATOR) |
                  (1 << Character.LINE_SEPARATOR) |
                  (1 << Character.PARAGRAPH_SEPARATOR)) >> getType(codePoint)) & 1)
            != 0;
    }

    /**
     * 确定指定字符依据 Java 标准是否为空白字符。
     * 对于ascii表中9到13包括9和13的unicode返回true
     */
    public static boolean isWhitespace(char ch) {
        return isWhitespace((int)ch);
    }

    /**
     * 确定指定字符依据 Java 标准是否为空白字符。
     * 对于ascii表中9到13包括9和13的unicode返回true
     */
    public static boolean isWhitespace(int codePoint) {
        return CharacterData.of(codePoint).isWhitespace(codePoint);
    }

    /**
     * 确定指定字符是否为 ascii表中的控制字符
     */
    public static boolean isISOControl(char ch) {
        return isISOControl((int)ch);
    }

    /**
     * 确定指定Unicode 代码点是否为 ascii表中的控制字符
     */
    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));
    }

    /**
     * 返回指示字符的常规类别的值。
     * 其中数字:9,小写字母:2,大写 字母:1 转义字符:24 转义序列:15 ……
     */
    public static int getType(char ch) {
        return getType((int)ch);
    }

    /**
     * 返回指示unicode代码点的常规类别的值。
     * 其中数字:9,小写字母:2,大写 字母:1 转义字符:24 转义序列:15 ……
     */
    public static int getType(int codePoint) {
        return CharacterData.of(codePoint).getType(codePoint);
    }

    /**
     * 返回数字digit在进制radix中是用什么字符表示的
     * 例如13在16进制中用d表示的,所以方法forDigit(13, 16)返回d
     */
    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);
    }

    /**
     * 返回给定字符的 Unicode 方向属性。
     */
    public static byte getDirectionality(char ch) {
        return getDirectionality((int)ch);
    }

    /**
     * 返回给定字符(Unicode 代码点)的 Unicode 方向属性。
     */
    public static byte getDirectionality(int codePoint) {
        return CharacterData.of(codePoint).getDirectionality(codePoint);
    }

    /**
     * 确定指定字符依据 Unicode 规范是否对称。
     */
    public static boolean isMirrored(char ch) {
        return isMirrored((int)ch);
    }

    /**
     * 确定指定字符(Unicode 代码点)依据 Unicode 规范是否对称。
     */
    public static boolean isMirrored(int codePoint) {
        return CharacterData.of(codePoint).isMirrored(codePoint);
    }

    /**
     * 返回(this.value-anotherCharacter.value)
     */
    public int compareTo(Character anotherCharacter) {
        return compare(this.value, anotherCharacter.value);
    }

    /**
     * 返回x-y
     */
    public static int compare(char x, char y) {
        return x - y;
    }

    /**
     * 
     */
    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);
    }

    /**
     * char类型占多少位
     */
    public static final int SIZE = 16;

    /**
     * char类型占两个字节
     */
    public static final int BYTES = SIZE / Byte.SIZE;

    /**
     * 返回通过反转指定 char 值中的字节顺序而获得的值。即前8位和后8位互换
     */
    public static char reverseBytes(char ch) {
        return (char) (((ch & 0xFF00) >> 8) | (ch << 8));
    }

    /**
     * 返回指定字符的Unicode名称  ,或者如果代码点是空 则返回unassigned 。 
     * 例如ascii表中的D的代码点是68,方法返回LATIN CAPITAL LETTER D
     */
    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);
    }
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325990332&siteId=291194637