java Integer源码阅读

参考博客 :
Java 源码学习系列(三)——Integer
求二进制数中1的个数
Java源码 Integer.bitCount实现过程

类定义

注意:源码是jdk1.7.0_79的

public final class Integer extends Number implements Comparable<Integer>
  • Integer 是 final 的不能被继承。
  • Integer 继承了 Number 抽象类。(转化成其他数值基本类型与byte类型)
  • Integer 实现了 Comparable 接口。(可以调用compareTo方法与Integer类型比较大小)
//最小值  补码
public static final int   MIN_VALUE = 0x80000000;
//最大值  正数和0补码与原码相同
public static final int   MAX_VALUE = 0x7fffffff; 
//int.class
public static final Class<Integer>  TYPE = (Class<Integer>) Class.getPrimitiveClass("int");
构造函数:
//私有变量 final只能赋值一次 Integer所包装的int值
private final int value;

//构造函数 - 接收一个int类型值
public Integer(int value) {
    this.value = value;
}
//构造函数 - 接收String解析成10进制int
public Integer(String s) throws NumberFormatException {
    this.value = parseInt(s, 10);
}
valueOf方法详解:
//如果i的值在 - 128 到 127(可配置)之间,取IntegerCache.cache中缓存的对象返回
//否则 new Integer(i)返回
public static Integer valueOf(int i) {
    assert IntegerCache.high >= 127;
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

/**
 * Cache to support the object identity semantics of autoboxing for values between
 * -128 and 127 (inclusive) as required by JLS.
 *
 * The cache is initialized on first usage.  The size of the cache
 * may be controlled by the -XX:AutoBoxCacheMax=<size> option.
 * During VM initialization, java.lang.Integer.IntegerCache.high property
 * may be set and saved in the private system properties in the
 * sun.misc.VM class.
 */
//静态内部类 存放 -128 - 127(默认)之间的缓存Integer对象
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
        //默认最大127
        int h = 127;
        //配置参数java.lang.Integer.IntegerCache.high可修改
        String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            //参数解析成int
            int i = parseInt(integerCacheHighPropValue);
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            //最大值范围 Integer.MAX_VALUE - 128 - 1 ;
            h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
        }
        high = h;
        //创建cache,并对cache进行初始化
        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
    }
    //私有构造函数,不能类外实例化,这个内部类不需要实例,只需要静态的存储数组cache
    private IntegerCache() {}
}

注意: 当在代码中这样写 Integer i = 10 ; 这句编译成 Integer i = Integer.valueOf(10);
这时只要int值在cache范围中,会直接返回缓存的对象.

可以写一个简单的类测试下

public class Test {
    public static void main(String[] args) {
        Integer j = 10;     
    }
}

使用 javap工具进行反编译
可以看到Main方法里 先向操作数栈写入常量 10 ,调用Integer.valueOf方法来赋值
同样的Integer类型赋值给int反编译可以看到调用了intValue方法.

可以参考: 从Java代码到字节码(1)

Classfile /D:/test/Test.class
  Last modified 2017-3-2; size 331 bytes
  MD5 checksum 117f6bcda0214e440d161a207b99ccf3
  Compiled from "Test.java"
public class Test
  SourceFile: "Test.java"
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_SUPER

Constant pool:
   #1 = Methodref          #4.#13         //  java/lang/Object."<init>":()V
   #2 = Methodref          #14.#15        //  java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   #3 = Class              #16            //  Test
   #4 = Class              #17            //  java/lang/Object
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Utf8               Code
   #8 = Utf8               LineNumberTable
   #9 = Utf8               main
  #10 = Utf8               ([Ljava/lang/String;)V
  #11 = Utf8               SourceFile
  #12 = Utf8               Test.java
  #13 = NameAndType        #5:#6          //  "<init>":()V
  #14 = Class              #18            //  java/lang/Integer
  #15 = NameAndType        #19:#20        //  valueOf:(I)Ljava/lang/Integer;
  #16 = Utf8               Test
  #17 = Utf8               java/lang/Object
  #18 = Utf8               java/lang/Integer
  #19 = Utf8               valueOf
  #20 = Utf8               (I)Ljava/lang/Integer;
{
  public Test();
    flags: ACC_PUBLIC

    Code:
      stack=1, locals=1, args_size=1
         0: aload_0       
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return        
      LineNumberTable:
        line 1: 0

  public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC

    Code:
      stack=1, locals=2, args_size=1
         0: bipush        10
         2: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
         5: astore_1      
         6: return        
      LineNumberTable:
        line 3: 0
        line 4: 6
}
String 转 Integer(int)

简单说明字符串解析数字的规则:
1 判断第一位是否符号位,进行特殊处理
2 根据进制解析每一位字符的数值,比如12345字符串代码中的算法:(((((((-1) * 10 - 2) * 10 - 3) * 10) - 4) * 10) - 5 * 10);每一个括号是一次循环,取负是为了方便校验. 最后得出结果在返回正确的符号.
进行两次校验(确保不要超出int范围):
+ 第一次是 得出结果未乘以进制前的负数 要大于 limit(负数)/进制 (确保乘以进制不会超出int范围)
+ 第二次校验乘以进制后结果 result(负数) 要大于 limit(负数) + 这次的解析的数字(正数)(确保加上解析的数字不会超出int范围)


/**
*  Examples:
* parseInt("0", 10) returns 0
* parseInt("473", 10) returns 473
* parseInt("+42", 10) returns 42
* parseInt("-0", 10) returns 0
* parseInt("-FF", 16) returns -255
* parseInt("1100110", 2) returns 102
* parseInt("2147483647", 10) returns 2147483647
* parseInt("-2147483648", 10) returns -2147483648
* parseInt("2147483648", 10) throws a NumberFormatException
* parseInt("99", 8) throws a NumberFormatException
* parseInt("Kona", 10) throws a NumberFormatException
* parseInt("Kona", 27) returns 411787
*/
//静态方法 s:要转int的字符串 radix:进制
public static int parseInt(String s, int radix)
            throws NumberFormatException
{
    /*
   * WARNING: This method may be invoked early during VM initialization
     * before IntegerCache is initialized. Care must be taken to not use
     * the valueOf method.
       */

    if (s == null) {
        throw new NumberFormatException("null");
    }
    //进制 必须 大于等于 2 小于等于 36
    if (radix < Character.MIN_RADIX) {
        throw new NumberFormatException("radix " + radix +
                                        " less than Character.MIN_RADIX");
    }

    if (radix > Character.MAX_RADIX) {
        throw new NumberFormatException("radix " + radix +
                                        " greater than Character.MAX_RADIX");
    }

    int result = 0;
    boolean negative = false; //是否负数
    int i = 0, len = s.length();
    //负数的话 limit 取值 Integer.MIN_VALUE :-2147483648
    //正数取值 -Integer.MAX_VALUE :-2147483647
    int limit = -Integer.MAX_VALUE; 
    int multmin;
    int digit;

    if (len > 0) {
        //取第一个字符,判断是否负数
        char firstChar = s.charAt(0);
        //如果第一个字符是符号位,解析符号赋值negative,并且将i 指向第二位字符
        if (firstChar < '0') { // Possible leading "+" or "-"
            if (firstChar == '-') {
                negative = true;
                limit = Integer.MIN_VALUE;
            } else if (firstChar != '+')
                throw NumberFormatException.forInputString(s);

            if (len == 1) // Cannot have lone "+" or "-"
                throw NumberFormatException.forInputString(s);
            i++; //自增,指向第二个字符
        }
        // 限制的最大值 / 进制 , 是解析结果没有 * 进制前 限制,最大的值,超过则说明解析字符串 超过int的最大范围(正数负数limit不同)
        multmin = limit / radix;
        //循环取出所有的字符
        while (i < len) {
            // Accumulating negatively avoids surprises near MAX_VALUE
            //字符根据进制获取数值,不能转换的返回-1
            digit = Character.digit(s.charAt(i++),radix);
            if (digit < 0) {
                throw NumberFormatException.forInputString(s);
            }
            //没乘以进制之前与 limit / radix比较,因为用负数比较,如果result 小于 limit / radix,则字符串解析值大于int范围.
            if (result < multmin) {
                throw NumberFormatException.forInputString(s);
            }
            result *= radix;
            //乘以进制后 校验, result(负数) < limit(负数) + digit(这次解析到的数字,正数)  则超出int范围
            //result < limit + digit
            if (result < limit + digit) {
                throw NumberFormatException.forInputString(s);
            }
            //result 赋值为 负的 字符解析的数值
            result -= digit;
        }
    } else {
        throw NumberFormatException.forInputString(s);
    }
    //result 的到的都是负数,进行加符号返回
    return negative ? result : -result;
   }

字符串解析成int 的核心方法就是parseInt方法,其他字符串解析方法都是调用这个方法.

  • Integer(String s) 构造方法
  • int parseInt(String s)
  • int parseInt(String s, int radix) 核心方法
  • Integer valueOf(String s, int radix)
  • Integer valueOf(String s)
  • Integer getInteger(String nm, Integer val)
  • Integer getInteger(String nm, int val)
  • Integer getInteger(String nm)
  • Integer decode(String nm)
//构造函数
public Integer(String s) throws NumberFormatException {
        this.value = parseInt(s, 10);
}

public static int parseInt(String s) throws NumberFormatException{
        return parseInt(s,10);
}

public static Integer valueOf(String s, int radix) throws NumberFormatException {
        return Integer.valueOf(parseInt(s,radix));
}

public static Integer valueOf(String s) throws NumberFormatException {
        return Integer.valueOf(parseInt(s, 10));
}
//注意这个nm 是 系统属性名字 , 通过 System.getProperty(nm)得到数字字符串调用Integer.decode解析成数字,第二个参数默认值
public static Integer getInteger(String nm, Integer val) {
    String v = null;
    try {
        v = System.getProperty(nm);
    } catch (IllegalArgumentException e) {
    } catch (NullPointerException e) {
    }
    if (v != null) {
        try {
            return Integer.decode(v);
        } catch (NumberFormatException e) {
        }
    }
    return val;
}
//val是默认值
public static Integer getInteger(String nm, int val) {
    Integer result = getInteger(nm, null);
    return (result == null) ? Integer.valueOf(val) : result;
 }

public static Integer getInteger(String nm) {
        return getInteger(nm, null);
}

//这个方法是解析16进制 8进制字符串的.
//以0x 0X # 开头的是16进制
//以 0 开头(并且长度大于1)的是 8 进制
//其他是10进制
public static Integer decode(String nm) throws NumberFormatException {
    int radix = 10;
    int index = 0;
    boolean negative = false;
    Integer result;

    if (nm.length() == 0)
        throw new NumberFormatException("Zero length string");
    char firstChar = nm.charAt(0);
    // Handle sign, if present
    //判断正负数 index记录数字开始的位置(跳过符号 进制开头)
    if (firstChar == '-') {
        negative = true;
        index++;
    } else if (firstChar == '+')
        index++;

    // Handle radix specifier, if present
    //0x 开头 0X 开头 16进制
    if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
        index += 2;
        radix = 16;
    } else if (nm.startsWith("#", index)) { //#开头 16进制
        index++;
        radix = 16;
    } else if (nm.startsWith("0", index) && nm.length() > 1 + index) {
        //以0开头,并且去除符号位数大于1 是8进制
        index++;
        radix = 8;
    }
    //nm 第index位是已 - 或 + 开头,格式错误
    if (nm.startsWith("-", index) || nm.startsWith("+", index))
        throw new NumberFormatException("Sign character in wrong position");
    //刨除符号位 进制格式位,其余数字调用Integer.valueOf(String,int) -Integer.parseInt(String, int)来解析数字
    try {
        //注意 这里传的nm.substring(index)是正数,正数解析会比负数小1,所以如果这个数字是Integer.MIN_VALUE,去掉符号位,会导致抛错
        result = Integer.valueOf(nm.substring(index), radix);
        //加上符号
        result = negative ? Integer.valueOf(-result.intValue()) : result;
    } catch (NumberFormatException e) {
        // If number is Integer.MIN_VALUE, we'll end up here. The next line
        // handles this case, and causes any genuine format error to be
        // rethrown.
        //再重新解析一次,负数加上符号位,排除Integer.MIN_VALUE的错误
        String constant = negative ? ("-" + nm.substring(index)) : nm
                .substring(index);
        result = Integer.valueOf(constant, radix);
    }
    return result;
}
int 转 String

涉及方法:
- String toString(int i, int radix)
- String toString(int i)
- String toString()
- String toHexString(int i)
- String toOctalString(int i)
- String toBinaryString(int i)
- String toUnsignedString(int i, int shift)

首先看 String toString(int i)方法:

/**
 * Returns a {@code String} object representing the
 * specified integer. The argument is converted to signed decimal
 * representation and returned as a string, exactly as if the
 * argument and radix 10 were given as arguments to the {@link
 * #toString(int, int)} method.
 *
 * @param   i   an integer to be converted.
 * @return  a string representation of the argument in base&nbsp;10.
 */
public static String toString(int i) {
    if (i == Integer.MIN_VALUE)
        return "-2147483648";
    //获取数字的位数,Integer.MIN_VALUE特殊处理,以为Integer.MIN_VALUE取负超出int最大范围.可以测试 -Integer.MIN_VALUE = Integer.MIN_VALUE,
    //求补码得到该数字的 取负(-), Integer.MIN_VALUE再求补码等于自身.
    int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
    //int转String的char数组
    char[] buf = new char[size];
    //调用这个方法为buf填充值
    getChars(i, size, buf);
    return new String(buf, true);
}

final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE };

// Requires positive x
static int stringSize(int x) {
    for (int i=0; ; i++)
        if (x <= sizeTable[i])
            return i+1;
}


/**
 * Places characters representing the integer i into the
 * character array buf. The characters are placed into
 * the buffer backwards starting with the least significant
 * digit at the specified index (exclusive), and working
 * backwards from there.
 *
 * Will fail if i == Integer.MIN_VALUE
 */
 //参数 i:转String的数字, index:数字的最大位数, buf:存放数字转的字符数组
static void getChars(int i, int index, char[] buf) {
    int q, r;
    int charPos = index;
    char sign = 0;
    //数字小于0 ,转成正数,对Integer.MIN_VALUE无效
    if (i < 0) {
        sign = '-';
        i = -i;
    }

    // Generate two digits per iteration
    //每次生成两位放入buf最高位中
    while (i >= 65536) {
        q = i / 100;
        // really: r = i - (q * 100);
        // q*(64 + 32 + 4) = q*100,移位运算比较快
        // i - q*100 得到 i 的最后两位数,i = q 剔除i的后两位
        r = i - ((q << 6) + (q << 5) + (q << 2));
        i = q;
        //通过查询DigitOnes DigitTens数组快速找到最后两位字符
        buf [--charPos] = DigitOnes[r];
        buf [--charPos] = DigitTens[r];
    }

    // Fall thru to fast mode for smaller numbers
    // assert(i <= 65536, i);
    // i < 65536进行转换
    // 65536 * 52429 数字大于了int的最大值范围,然而没有超出2^32的范围
    // 无符号右移 19位 , 相当于 (i * 52429)/ 2^19(524288) 相当于 i / 10
    // 详细论证看开头的参考博客,里面进行了详细论证
    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;
    }
}
//用于快速查找 数字对应的字符
final static char [] DigitTens = {
    '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
    '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
    '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
    '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
    '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
    '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
    '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
    '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
    '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
    '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
    } ;

final static char [] DigitOnes = {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    } ;

其他方法:String toString(int i, int radix)

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

        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] = '-';
        }
        //截取正确的位数
        return new String(buf, charPos, (33 - charPos));
    }

    /**
     * All possible chars for representing a number as a String
     */
    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'
    };

其他方法: 转2 8 16进制 无符号数
+ String toUnsignedString(int i, int shift)
+ String toBinaryString(int i)
+ String toOctalString(int i)
+ String toHexString(int i)


/**
 * Convert the integer to an unsigned number.
 * 转成无符号数
 * 私有静态方法,转换进制为 2的shift次方
 * 如转16 进制 toUnsignedString(i, 4)
 */
private static String toUnsignedString(int i, int shift) {
    //char 最长 2 进制 32 位 (无符号)
    char[] buf = new char[32];
    int charPos = 32;
    int radix = 1 << shift; //得到进制
    //radix - 1 与 i 做与操作,保留下 最后shift位二进制数,
    // 获取digits中对应进制的数, i 在无符号右移 shift 位
    int mask = radix - 1;
    do {
        buf[--charPos] = digits[i & mask];
        i >>>= shift;
    } while (i != 0);
    //截取buf中有值的位数.
    return new String(buf, charPos, (32 - charPos));
}
//转2进制
public static String toBinaryString(int i) {
    return toUnsignedString(i, 1);
}
//转8进制
public static String toOctalString(int i) {
    return toUnsignedString(i, 3);
}
//转16进制
public static String toHexString(int i) {
    return toUnsignedString(i, 4);
}
继承Number的方法
  • int intValue();
  • long longValue();
  • float floatValue();
  • double doubleValue();
  • byte byteValue();
  • short shortValue();

将int类型强转成其他类型.(short,byte会截断高位)

实现Comparable接口
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);
}
其他方法 位运算
  • static int highestOneBit(int i)
  • static int lowestOneBit(int i)
  • static int numberOfLeadingZeros(int i)
  • static int numberOfTrailingZeros(int i)
  • static int bitCount(int i)
  • static int rotateLeft(int i, int distance)
  • static int rotateLeft(int i, int distance)
  • static int reverse(int i)
  • static int signum(int i)
  • static int reverseBytes(int i)
/**
 * 方法用途 - 取一个二进制数最先出现1的 位保留1 其余位都变成 0
 * 比如 0100_1111 -> 0100_0000 , 保留最先出现 1的位,其余变 0 返回最高位为1, 其它位为0的数 
 * 计算方式 :比如一个二进制最高位第 n位  ,最低位为第1 位 :
 * n , n|n-1 , n|n-1|n-2 , n|n-1|n-2|n-3, ... , n|n-1|...|2|1
 * 那么最先出现 1 的位与其后的位 都是 1 
 * i - i 无符号向右移 1 位  得到最先出现 1的最高位为1 ,其余位都是 0 
 * (如  0111_1111 - 0011_1111 = 0100_0000)
 */
public static int highestOneBit(int i) {
    // HD, Figure 3-1
    i |= (i >>  1);
    i |= (i >>  2);
    i |= (i >>  4);
    i |= (i >>  8);
    i |= (i >> 16);
    return i - (i >>> 1);
}

//方法功能-得到最低位出现 1的其余位为0 的数
public static int lowestOneBit(int i) {
    // HD, Section 2-1
    //计算方式 : i补码 & i -> i的反码+ 1 & i 
    //因为 i反码+1 使最低位出现1 的变成 1,更低位的都是0,  i补码 & i得到正确的数
    return i & -i;
}
//方法功能 - 取最高位为 1 前面 0 位的数量
//二分查找进行计算,不断缩小范围
public static int numberOfLeadingZeros(int i) {
    // HD, Figure 5-6
    if (i == 0)
        return 32;
    int 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;
}

//方法说明 - 取最低位是1 后面的 0 位的个数,二分查找法
public static int numberOfTrailingZeros(int i) {
    // HD, Figure 5-14
    int y;
    if (i == 0) return 32;
    int n = 31;
    y = i <<16; if (y != 0) { n = n -16; i = y; }
    y = i << 8; if (y != 0) { n = n - 8; i = y; }
    y = i << 4; if (y != 0) { n = n - 4; i = y; }
    y = i << 2; if (y != 0) { n = n - 2; i = y; }
    return n - ((i << 1) >>> 31);
}

//计算 - 2进制是 1 的位数
//二分法 先计算每两位中的1的个数 , 再计算4位中1的个数 .. 32位中1的个数
//计算方式详细可以看参考 Java源码 Integer.bitCount实现过程 的博客
public static int bitCount(int i) {
    // HD, Figure 5-2
    i = i - ((i >>> 1) & 0x55555555);
    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
    i = (i + (i >>> 4)) & 0x0f0f0f0f;
    i = i + (i >>> 8);
    i = i + (i >>> 16);
    return i & 0x3f;
}

//方法功能 - 循环左移 distance 位
//注意 移位运算32位 只有distance数字的低五位有效,64位数字 低6位有效
//所以 右移-distance位可以表示成 右移32 - distance位.
public static int rotateLeft(int i, int distance) {
    return (i << distance) | (i >>> -distance);
}
//方法功能 - 循环右移 distance 位
public static int rotateRight(int i, int distance) {
    return (i >>> distance) | (i << -distance);
}

//方法功能 - 翻转一个二进制数(32位,最低位变成最高位,第二 低位变成第二高位),同bitCount计算方式一样, 先翻转每两位的顺序,再翻转每4位中的顺序,再翻转每8位中的顺序,让后的到32位翻转后顺序
public static int reverse(int i) {
    // HD, Figure 7-1
    i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
    i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
    i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
    i = (i << 24) | ((i & 0xff00) << 8) |
        ((i >>> 8) & 0xff00) | (i >>> 24);
    return i;
}
//获得符号位 - 正数返回 1, 负数返回 -1, 0 返回 0
public static int signum(int i) {
    // HD, Section 2-7
    return (i >> 31) | (-i >>> 31);
}
//方法功能 - 翻转一个二进制数(最低8位变成最高8位,8位内顺序不翻转),方法原理同reverse
public static int reverseBytes(int i) {
    return ((i >>> 24)           ) |
        ((i >>   8) &   0xFF00) |
        ((i <<   8) & 0xFF0000) |
        ((i << 24));
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值