美文网首页
Character和Integer

Character和Integer

作者: hklbird | 来源:发表于2016-08-08 17:23 被阅读222次

这里主要通过阅读源码了解character的一些特性

Character类的结构

public final
class Character implements java.io.Serializable, Comparable<Character> {
……………………
private final char value;
}

可以看到类无法覆盖父类,同时实现了序列化接口和比较接口。存储内容的char型变量为final,无法被修改值。
这里有一个很有意思的类CharacterCache,代码如下:

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

仔细观察接下去的代码我们可以知道,这个类相当于字符集合的一个缓存机制。这里有一个类方法(工厂方法)可以产生Character对象,首先将从cache中取值。

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

Integer类的结构

public final class Integer extends Number implements Comparable<Integer> {
private final int value;
…………………………
 public Integer(int value) {
        this.value = value;
    }
    public Integer(String s) throws NumberFormatException {
        this.value = parseInt(s, 10);
    }
}
// 可以看到比较值的运算时直接使用值的
 public int compareTo(Integer anotherInteger) {
        return compare(this.value, anotherInteger.value);
    }
  public static int compare(int x, int y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }

这里可以看到Integer主要的内容存储方式是和Character极为相似的,除此之外,Integer也有Cache。

 private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }
 public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

这里可以看到Integer同样有cache,也同样有工厂方法在产生对象的时候使用cache中存储的变量。这里的大小是-128——127。

Integer的一些特性

// 用于数字字符串的转换
 final static char[] digits = {
        '0' , '1' , '2' , '3' , '4' , '5' ,
        '6' , '7' , '8' , '9' , 'a' , 'b' ,
        'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
        'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
        'o' , 'p' , 'q' , 'r' , 's' , 't' ,
        'u' , 'v' , 'w' , 'x' , 'y' , 'z'
    };
public static String toString(int i, int radix) {
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
            radix = 10;

        /* Use the faster version */
        if (radix == 10) {
            return toString(i);
        }
        // 我们可以知道int类型是四个字节32位的数
        char buf[] = new char[33];
        boolean negative = (i < 0);
        int charPos = 32;
        if (!negative) {
            i = -i;
        }
        while (i <= -radix) {
            buf[charPos--] = digits[-(i % radix)];
            i = i / radix;
        }
        buf[charPos] = digits[-i];
        if (negative) {
            buf[--charPos] = '-';
        }
          //根据内容创建新的String类型对象
        return new String(buf, charPos, (33 - charPos));
    }

上述的是普通的toString,从函数体中我们看到当radix==10使,显然使用的是其他的策略。

public static String toString(int i) {
        if (i == Integer.MIN_VALUE)
            return "-2147483648";
//StringSize缓存9、99……的int表,从而返回相应的int类型长度
        int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
        char[] buf = new char[size];
        getChars(i, size, buf);
        return new String(buf, true);
    }
static void getChars(int i, int index, char[] buf) {
        int q, r;
        int charPos = index;
        char sign = 0;

        if (i < 0) {
            sign = '-';
            i = -i;
        }

        // Generate two digits per iteration
        while (i >= 65536) {
            q = i / 100;
        // really: r = i - (q * 100);将乘法转化为位运算
            r = i - ((q << 6) + (q << 5) + (q << 2));
            i = q;
            buf [--charPos] = DigitOnes[r];
            buf [--charPos] = DigitTens[r];
        }

        // Fall thru to fast mode for smaller numbers
        // assert(i <= 65536, i);
        for (;;) {
        //这个核心算法反正我是没法理解,以后再理解吧
            q = (i * 52429) >>> (16+3);
            r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
            buf [--charPos] = digits [r];
            i = q;
            if (i == 0) break;
        }
        if (sign != 0) {
            buf [--charPos] = sign;
        }
    }

总结

1.Character和Integer都有缓存机制,character为0——127、Integer为-128——127。
2.Integer类型的toString过程中显然用缓存字符矩阵的方法提高效率。此外,可以发现,源码的扩大十倍可以用等价的位运算来替代。

相关文章

网友评论

      本文标题:Character和Integer

      本文链接:https://www.haomeiwen.com/subject/pkjrsttx.html