欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > > 文章正文

Java Object 通用方法 toString() 之 Integer.toHexString(),

来源: javaer 分享于  点击 9487 次 点评:132

Java Object 通用方法 toString() 之 Integer.toHexString(),


toString()的源代码如下:
public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
getClass() 返回类对象 ;getName() 以String形式返回类对象的名称(包换包名);Integer.toHexString(hashCode()) 以对象的哈希码为参数,以16进制无符号整数形式返回此哈希码的字符串表示形式;下面主要分析下Integer.toHexString()以下是其源码:
public static String toHexString(int i) {
    return toUnsignedString0(i, 4);
}
private static String toUnsignedString0(int val, int shift) {
    // assert shift > 0 && shift <=5 : "Illegal shift value";
    int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val); 	// (1)
    int chars = Math.max(((mag + (shift - 1)) / shift), 1);		// (2)
    char[] buf = new char[chars];

    formatUnsignedInt(val, shift, buf, 0, chars);			// (3)

    // Use special constructor which takes over "buf".
    return new String(buf, true);
}
(1) 这一步主要是为了计算val值对应的二进制数中除去首部0的个数后剩下的有效位数mag。    a.Integer.SIZE: int在jvm中占4个字节,共32位;    b.首部0的个数:是指从左边第一个位置开始累加0的个数,一直加到第一个非零值;    c.方法numberOfLeadingZeros() 就是计算首部0的个数。下面看看numberOfLeadingZeros()的源码,源码应用了二分查找,先把32位整形分为高16位和低16位查找非零数,在对高16位进行或低16位进行二分,以此类推,直到找到左边第一个非零值的位置。
public static int numberOfLeadingZeros(int i) {
    // HD, Figure 5-6
    if (i == 0)
        return 32;
    // 初始首部0的个数:1 假定最高位有一个0,最后的时候会根据最高位是否位零补偿返回
    int n = 1;
    // 下面的代码主要是为了找出左边第一个非零值的位置
    // 采用二分查找的方法,首先将 i 无符号右移16位后,有两种情况(a, b):
    // a. 右移后 = 0,则第一个非零值出现在低16位,那么 i 首位至少有16个0(n=17),
    // 同时将 i 左移16位后赋值给自己(将低16位移到了高16位,这样可以使两种保持同一的状态进行后续判断);
    // b. 右移后!=0,则第一个非零值出现在高16位(n=1),继续在高16位中寻找;
    // 将高16位继续分为 高8位和低8位进行判断,一直二分到还有两位的时候;
    // 最后 i 无符号右移31位(结果要么是0要么是1),如果右移后为0,说明此时的最高位为0,无需补偿,直接返回 n;
    // 如果右移后是1,则说明最高位不为0,需补偿,返回 n-1;
    if (i >>> 16 == 0) { n += 16; i <<= 16; }
    if (i >>> 24 == 0) { n +=  8; i <<=  8; }
    if (i >>> 28 == 0) { n +=  4; i <<=  4; }
    if (i >>> 30 == 0) { n +=  2; i <<=  2; }
    n -= i >>> 31;
    return n;
}
(2) int chars = Math.max(((mag + (shift - 1)) / shift), 1):计算 i 的有效二进制的位数所需要占的字节数(即对应的16进制的有效位数),toString()方法是以16进制返回,这里就以16进制来解释。根据二进制和16进制的转化关系可以知道,每4个二进制位代表一个16进制数,mag是有效的二进制位个数,所以想要计算需要的字节数可能遇到如下三种情况:         a. mag=0,那么只需要一个字节即可;
   b.mag !=0, 是4的整数倍,则需要mag/4 个字节;
   c.mag !=0,不是4的整数倍,则需要mag/4 +1 个字节;
(mag + (shift - 1)) / shift 可以解决后面两种情况;Math.max(((mag + (shift - 1)) / shift), 1) 可以解决这三种情况。(3) 在toString() 方法中,formatUnsignedInt() 完成的功能就是将val值以16进制数形式存进buf数组中。先进行按位与运算,算出val的二进制中低四位对应的10进制的值,在 digits 数组中获取对应的16进制值,存进buf字节数组中;后将val无符号右移4位,保持在最低四位与mask进行按位与运算,在 digits 数组中获取对应的16进制值,存进buf字节数组中,以此循环,直到val=0或者charPos<=0后退出循环。
     static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
        int charPos = len;
        int radix = 1 << shift;
        int mask = radix - 1;
        do {
            buf[offset + --charPos] = Integer.digits[val & mask];
            val >>>= shift;
        } while (val != 0 && charPos > 0);

        return charPos;
    }














相关文章

    暂无相关文章

用户点评