Integer源码分析。

太过爱你忘了你带给我的痛 2024-02-19 15:12 115阅读 0赞
  1. public final class Integer extends Number implements Comparable<Integer> {
  2. /*
  3. * 继承Number类提供将表示的数值转换为 byte、double、float、int、long 和 short 的方法。<br />
  4. * 实现Comparable接口,获取到compareTo方法。
  5. */
  6. // 值为 -231 的常量,它表示 int 类型能够表示的最小值。
  7. public static final int MIN_VALUE = 0x80000000;
  8. // 值为 2的31方-1 的常量,它表示 int 类型能够表示的最大值
  9. public static final int MAX_VALUE = 0x7fffffff;
  10. // 表示基本类型 int 的 Class 实例
  11. public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");
  12. // 用于将数字表示为字符串的所有可能字符,支持二进制到三十六进制(故需要36个字符)
  13. final static char[] digits = {
  14. '0' , '1' , '2' , '3' , '4' , '5' ,
  15. '6' , '7' , '8' , '9' , 'a' , 'b' ,
  16. 'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
  17. 'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
  18. 'o' , 'p' , 'q' , 'r' , 's' , 't' ,
  19. 'u' , 'v' , 'w' , 'x' , 'y' , 'z'
  20. };
  21. /**
  22. * 转化对应进制的数字为十进制
  23. * @param i 要转换成字符串的整数
  24. * @param radix 进制数
  25. * @return String
  26. */
  27. public static String toString(int i, int radix) {
  28. // 如果进制数小于2进制 或者大于 26进制,则改用十进制。
  29. if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
  30. radix = 10;
  31. /* 如果是十进制,用最快的版本 */
  32. if (radix == 10) {
  33. return toString(i);
  34. }
  35. // 创建一个33位的字符数组(负数时:1位符号位+32位数字;正数时,32位数字)
  36. char buf[] = new char[33];
  37. boolean negative = (i < 0);
  38. int charPos = 32;
  39. // 将正数转为负数进行运算,防止负数转为正数的溢出情况
  40. if (!negative) {
  41. i = -i;
  42. }
  43. // 循环判断当前转换的字符是否小于计数的相反数
  44. while (i <= -radix) {
  45. // //根据余数的相反数在digits数组中获取相应的字符,倒序存放到buf[]数组里
  46. buf[charPos--] = digits[-(i % radix)];
  47. i = i / radix;
  48. }
  49. buf[charPos] = digits[-i];
  50. // 若是负数,加减号
  51. if (negative) {
  52. buf[--charPos] = '-';
  53. }
  54. // 返回一个字符串,参数为char数组、起始位置、字符长度
  55. return new String(buf, charPos, (33 - charPos));
  56. }
  57. /**
  58. * 返回当前整数的16进制的字符串形式
  59. * @param i 要转换成字符串的整数
  60. */
  61. public static String toHexString(int i) {
  62. return toUnsignedString(i, 4);
  63. }
  64. /**
  65. * 返回当前整数的8进制的字符串形式
  66. * @param i 要转换成字符串的整数
  67. * @return String
  68. */
  69. public static String toOctalString(int i) {
  70. return toUnsignedString(i, 3);
  71. }
  72. /**
  73. * 返回当前整数的2进制的字符串形式
  74. * @param i 要转换成字符串的整数
  75. * @return String
  76. */
  77. public static String toBinaryString(int i) {
  78. return toUnsignedString(i, 1);
  79. }
  80. /**
  81. * 返回当前整数i的shift进制的字符串形式的私有工具类
  82. * @param i 要转换成字符串的整数
  83. * @param shift 进制数
  84. * @return String
  85. */
  86. private static String toUnsignedString(int i, int shift) {
  87. // 当shift为1二进制时,char数组大小32刚好,而当shift为3,4时,数组大小有余
  88. char[] buf = new char[32];
  89. // 当数组有余时,便于取char数组中的数据
  90. int charPos = 32;
  91. // 算数左移,radix中间变量用于计算mask
  92. int radix = 1 << shift;
  93. // mask掩码用于获取i的shift位低位,mask二进制数每一位都是1
  94. int mask = radix - 1;
  95. do {
  96. //取出i二进制数低位shift位,将对应的字符存入buf
  97. //新建数组大小时[]填32,但是在数组赋值时[]填0~31
  98. buf[--charPos] = digits[i & mask];
  99. //逻辑右移,剔除已取出的shfit位低位
  100. i >>>= shift;
  101. } while (i != 0);
  102. return new String(buf, charPos, (32 - charPos));
  103. }
  104. /**
  105. * DigitTens和DigitOnes这两个常量数组主要是为了获取0到99之间某个数的十位和个位。
  106. */
  107. //取十位数
  108. final static char [] DigitTens = {
  109. '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
  110. '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
  111. '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
  112. '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
  113. '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
  114. '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
  115. '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
  116. '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
  117. '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
  118. '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
  119. } ;
  120. // 取个位数
  121. final static char [] DigitOnes = {
  122. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  123. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  124. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  125. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  126. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  127. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  128. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  129. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  130. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  131. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  132. } ;
  133. /**
  134. * 返回当前数字的字符串形式
  135. * @param i 十进制的整数
  136. * @return String
  137. */
  138. public static String toString(int i) {
  139. if (i == Integer.MIN_VALUE)
  140. return "-2147483648";
  141. // 判断是否为负数,计算长度
  142. int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
  143. char[] buf = new char[size];
  144. // 将数字分成一个个char,保存到buf数组中
  145. getChars(i, size, buf);
  146. return new String(buf, true);
  147. }
  148. /**
  149. * 将某个int型数值写入到字符数组中(若i等于Integer.MIN_VALUE,则为失败)
  150. * 该方法将int进行高两字节、低两字节分开处理
  151. * 几种运算的耗时长短:除法运算>乘法运算>移位结合加法的运算
  152. * @param i 需要处理的整数
  153. * @param index 整数长度
  154. * @param buf 字符数组
  155. * @return void
  156. */
  157. static void getChars(int i, int index, char[] buf) {
  158. int q, r;
  159. int charPos = index;
  160. char sign = 0;
  161. // 是否为负数,则将标志符号设为减号,然后i取相反数
  162. if (i < 0) {
  163. sign = '-';
  164. i = -i;
  165. }
  166. // 处理高两字节
  167. while (i >= 65536) {
  168. q = i / 100;
  169. // really: r = i - (q * 100);
  170. r = i - ((q << 6) + (q << 5) + (q << 2));
  171. // 将商赋给i,继续循环,直到小于65536
  172. i = q;
  173. // 取DigitOnes[r]的值其实取数字r%10的结果
  174. buf [--charPos] = DigitOnes[r];
  175. // 取DigitTens[r]的值其实取数字r/10的结果
  176. buf [--charPos] = DigitTens[r];
  177. }
  178. // 对于较小的数字,进入快速模式
  179. // 循环存放低两字节的数字存放到字符数组中空余位置
  180. for (;;) {
  181. // 右移19位
  182. /**
  183. * >>>: 无符号的右移
  184. * >>: 有符号的右移
  185. */
  186. // q=i/10
  187. q = (i * 52429) >>> (16+3);
  188. // r = i-(q*10)
  189. r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
  190. // 从digit数组中取数
  191. buf [--charPos] = digits [r];
  192. i = q;
  193. //整数写入字符数组完成
  194. if (i == 0) break;
  195. }
  196. //若整数是负数,需要在字符数组中加上'-'字符
  197. if (sign != 0) {
  198. buf [--charPos] = sign;
  199. }
  200. }
  201. // 用在判断一个int类型数字对应字符串的长度
  202. final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
  203. 99999999, 999999999, Integer.MAX_VALUE };
  204. /**
  205. * 判断一个int类型数字的长度
  206. * 要求正数
  207. * @param x int类型的正整数
  208. * @return
  209. */
  210. static int stringSize(int x) {
  211. for (int i=0; ; i++)
  212. if (x <= sizeTable[i])
  213. return i+1;
  214. }
  215. /**
  216. * 返回输入字符串的指定进制的正整数
  217. * @param s 需要转换的字符串
  218. * @param radix 当前字符串的数字部分的进制数(也就是s的进制)
  219. * @return int
  220. */
  221. public static int parseInt(String s, int radix)
  222. throws NumberFormatException
  223. {
  224. /*
  225. * 警告:此方法可以在VM初始化的早期调用
  226. * 在初始化IntegerCache之前。注意不要使用方法的值。
  227. */
  228. if (s == null) {
  229. throw new NumberFormatException("null");
  230. }
  231. if (radix < Character.MIN_RADIX) {
  232. throw new NumberFormatException("radix " + radix +
  233. " less than Character.MIN_RADIX");
  234. }
  235. if (radix > Character.MAX_RADIX) {
  236. throw new NumberFormatException("radix " + radix +
  237. " greater than Character.MAX_RADIX");
  238. }
  239. // 保存结果
  240. int result = 0;
  241. boolean negative = false;
  242. int i = 0, len = s.length();
  243. int limit = -Integer.MAX_VALUE;
  244. int multmin;
  245. int digit;
  246. //字符串长度大于0
  247. if (len > 0) {
  248. // 获取字符串的第一个字符
  249. char firstChar = s.charAt(0);
  250. // 如果第一个字符小于0
  251. if (firstChar < '0') {
  252. if (firstChar == '-') { // 负数
  253. negative = true;
  254. limit = Integer.MIN_VALUE;
  255. } else if (firstChar != '+') //不为正数
  256. throw NumberFormatException.forInputString(s);
  257. // 输入的转化字符串只有一个"+"或"-"
  258. if (len == 1)
  259. throw NumberFormatException.forInputString(s);
  260. i++;
  261. }
  262. // 限制的最小值(在对应进制的)
  263. multmin = limit / radix;
  264. // 将字符串的数字部分转为进制的数字(从左到右)
  265. while (i < len) {
  266. // 将字符串的数字部分的一个数字(对应进制),通过Character类转为进制的数
  267. // 若字符串中的某一个字符,在字符串进制下(radix)是无效的,则返回-1
  268. digit = Character.digit(s.charAt(i++),radix);
  269. if (digit < 0) {// 若返回-1(无效)
  270. throw NumberFormatException.forInputString(s);
  271. }
  272. if (result < multmin) {// 结果小于最小的值(目标进制下)
  273. throw NumberFormatException.forInputString(s);
  274. }
  275. // 结果:将结果乘上字符串进制数
  276. result *= radix;
  277. // 若结果小于最小值加上当前最字符值
  278. if (result < limit + digit) {
  279. throw NumberFormatException.forInputString(s);
  280. }
  281. // 将结果减去当前字符的值
  282. result -= digit;
  283. }
  284. } else {
  285. throw NumberFormatException.forInputString(s);
  286. }
  287. // 若是负数,则直接返回,若是正数,先取反结果再输出
  288. return negative ? result : -result;
  289. }
  290. /**
  291. * 返回指定字符串的int类型的数值,默认是10进制的
  292. * @param s 需要转换的字符串
  293. * @return int
  294. */
  295. public static int parseInt(String s) throws NumberFormatException {
  296. return parseInt(s,10);
  297. }
  298. /**
  299. * 返回指定转换进制的字符串的一个Integer对象
  300. * @param s 需要转换的字符串
  301. * @param radix 进制位
  302. * @return Integer
  303. */
  304. public static Integer valueOf(String s, int radix) throws NumberFormatException {
  305. return Integer.valueOf(parseInt(s,radix));
  306. }
  307. /**
  308. * 返回指定字符串的一个Integer对象,默认是10进制的
  309. * @param s 需要转换的字符串
  310. * @return Integer
  311. */
  312. public static Integer valueOf(String s) throws NumberFormatException {
  313. return Integer.valueOf(parseInt(s, 10));
  314. }
  315. /**
  316. * 缓存以支持自动装箱的对象标识语义,用于在-128和127(包括JLS要求的)。
  317. * 缓存在第一次使用时被初始化。缓存大小
  318. * 可以通过-XX:AutoBoxCacheMax=<size>选项进行控制。
  319. * 在VM初始化期间,java.lang.Integer.IntegerCache.high属性
  320. * 可以在Sun.misc.VM类。
  321. */
  322. private static class IntegerCache {
  323. static final int low = -128;
  324. // 高值可以通过属性配置:启动JVM时通过 -Djava.lang.Integer.IntegerCache,high=xxx进行设置
  325. static final int high;
  326. static final Integer cache[];
  327. static {
  328. // 可以通过属性配置高值
  329. int h = 127;
  330. // 读取JVM初始化时的属性
  331. String integerCacheHighPropValue =
  332. sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
  333. if (integerCacheHighPropValue != null) {
  334. int i = parseInt(integerCacheHighPropValue);
  335. i = Math.max(i, 127);
  336. // 最大数组大小是Integer.MAX_VALUE
  337. h = Math.min(i, Integer.MAX_VALUE - (-low));
  338. }
  339. // 未配置则为默认最高值127
  340. high = h;
  341. // 创建一个大小为(最大值-最小值+1)的数组
  342. cache = new Integer[(high - low) + 1];
  343. int j = low;
  344. // 创建对应大小的Integer对象,放入缓存的数组中
  345. for(int k = 0; k < cache.length; k++)
  346. cache[k] = new Integer(j++);
  347. }
  348. private IntegerCache() {}
  349. }
  350. /**
  351. * 返回一个表示指定的 int 值的 Integer 实例。
  352. * 如果不需要新的 Integer 实例,则通常应优先使用该方法,
  353. * 而不是构造方法 Integer(int),因为该方法有可能
  354. * 通过缓存经常请求的值而显著提高空间和时间性能。
  355. * @param i 指定的int值
  356. * @return Integer
  357. */
  358. public static Integer valueOf(int i) {
  359. assert IntegerCache.high >= 127;
  360. // 直接获得在[low,high]范围内的IntegerCache缓存的Integer对象,不在该范围则重新实例化Integer对象
  361. if (i >= IntegerCache.low && i <= IntegerCache.high)
  362. return IntegerCache.cache[i + (-IntegerCache.low)];
  363. return new Integer(i);
  364. }
  365. // 保存Integer类中的真实基本数据类型的值
  366. private final int value;
  367. /**
  368. * 构造一个新分配的 Integer 对象,它表示指定的 int 值。
  369. * @param value
  370. */
  371. public Integer(int value) {
  372. this.value = value;
  373. }
  374. /**
  375. * 构造一个新分配的 Integer 对象,
  376. * 它表示 String 参数所指示的 int 值。
  377. * 使用与 parseInt 方法(对基数为 10 的值)相同的方式将该字符串转换成 int 值。
  378. * @param s 指定的int值
  379. * @throws NumberFormatException
  380. */
  381. public Integer(String s) throws NumberFormatException {
  382. this.value = parseInt(s, 10);
  383. }
  384. /**
  385. * 以 byte 类型返回该 Integer 的值。
  386. */
  387. public byte byteValue() {
  388. return (byte)value;
  389. }
  390. /**
  391. * 以 short 类型返回该 Integer 的值。
  392. */
  393. public short shortValue() {
  394. return (short)value;
  395. }
  396. /**
  397. * 以 int 类型返回该 Integer 的值。
  398. */
  399. public int intValue() {
  400. return value;
  401. }
  402. /**
  403. * 以 long 类型返回该 Integer 的值。
  404. */
  405. public long longValue() {
  406. return (long)value;
  407. }
  408. /**
  409. * 以 float 类型返回该 Integer 的值。
  410. */
  411. public float floatValue() {
  412. return (float)value;
  413. }
  414. /**
  415. * 以 double 类型返回该 Integer 的值。
  416. */
  417. public double doubleValue() {
  418. return (double)value;
  419. }
  420. /**
  421. * 返回一个表示该 Integer 值的 String 对象。
  422. * 将该参数转换为有符号的十进制表示形式,
  423. * 并以字符串的形式返回它,
  424. * 就好像将该整数值作为参数赋予 toString(int) 方法一样。
  425. */
  426. public String toString() {
  427. return toString(value);
  428. }
  429. /**
  430. * 返回此 Integer 的哈希码
  431. */
  432. public int hashCode() {
  433. return value;
  434. }
  435. /**
  436. * 比较此对象与指定对象。当且仅当参数不为 null,
  437. * 并且是一个与该对象包含相同 int 值的 Integer 对象时,
  438. * 结果为 true。
  439. */
  440. public boolean equals(Object obj) {
  441. if (obj instanceof Integer) {
  442. return value == ((Integer)obj).intValue();
  443. }
  444. return false;
  445. }
  446. /**
  447. * 返回系统常量的int值,类似System.getProperty(str);
  448. * @param nm 属性名
  449. * @return Integer
  450. */
  451. public static Integer getInteger(String nm) {
  452. return getInteger(nm, null);
  453. }
  454. /**
  455. * 返回系统常量的int值,类似System.getProperty(str);
  456. * 如果为空,默认值为val
  457. * @param nm 属性名
  458. * @param val 给定默认值
  459. * @return Integer
  460. */
  461. public static Integer getInteger(String nm, int val) {
  462. Integer result = getInteger(nm, null);
  463. return (result == null) ? Integer.valueOf(val) : result;
  464. }
  465. /**
  466. * 返回具有指定名称的系统属性的整数值。
  467. * @param nm 属性名
  468. * @param val 给定默认值
  469. * @return Integer
  470. */
  471. public static Integer getInteger(String nm, Integer val) {
  472. String v = null;
  473. try {// 获取对应系统变量名的值
  474. v = System.getProperty(nm);
  475. } catch (IllegalArgumentException e) {
  476. } catch (NullPointerException e) {
  477. }
  478. if (v != null) {
  479. try {//返回字符串中的数字
  480. return Integer.decode(v);
  481. } catch (NumberFormatException e) {
  482. }
  483. }
  484. return val;
  485. }
  486. /**
  487. * 解码字符串转成Integer型对象
  488. * @param nm 要解码的 String
  489. * @throws NumberFormatException
  490. * @return Integer
  491. */
  492. public static Integer decode(String nm) throws NumberFormatException {
  493. // 十进制
  494. int radix = 10;
  495. // 当前判断完的字符数
  496. int index = 0;
  497. boolean negative = false;
  498. Integer result;
  499. if (nm.length() == 0)
  500. throw new NumberFormatException("Zero length string");
  501. // 获得字符串的第一个字符
  502. char firstChar = nm.charAt(0);
  503. if (firstChar == '-') {// 如果为负
  504. negative = true;
  505. index++;
  506. } else if (firstChar == '+')//为"+"的情况
  507. index++;
  508. // 然后剩下的字符串以0x或0X开头,表示十六进制
  509. if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
  510. index += 2;
  511. radix = 16;
  512. }
  513. else if (nm.startsWith("#", index)) {//或以#开头,表示十六进制
  514. index ++;
  515. radix = 16;
  516. }
  517. //若以0开头,且字符串长度大于当前判断字符数+1,,则为8进制
  518. else if (nm.startsWith("0", index) && nm.length() > 1 + index) {
  519. index ++;
  520. radix = 8;
  521. }
  522. // 再存在"-"/"+"这两字符,则抛出数字转化异常
  523. if (nm.startsWith("-", index) || nm.startsWith("+", index))
  524. throw new NumberFormatException("Sign character in wrong position");
  525. try {
  526. // 将剩下的字符串从某进制转为指定进制的数的包装类对象
  527. result = Integer.valueOf(nm.substring(index), radix);
  528. // 若是负数,取反包装类Integer中的value的值,再进行获取该基本数据类型的包装对象实例
  529. result = negative ? Integer.valueOf(-result.intValue()) : result;
  530. } catch (NumberFormatException e) {
  531. // 使用int类型参数转化出现异常,转而使用String类型参数进行转化
  532. String constant = negative ? ("-" + nm.substring(index))
  533. : nm.substring(index);
  534. // 转化字符串成对应的包装类的实例对象
  535. result = Integer.valueOf(constant, radix);
  536. }
  537. return result;
  538. }
  539. /**
  540. *比较两个 Integer 对象的value值大小
  541. */
  542. public int compareTo(Integer anotherInteger) {
  543. return compare(this.value, anotherInteger.value);
  544. }
  545. /**
  546. * 比较两个int类型的值的大小
  547. * @param x
  548. * @param y
  549. * @return int
  550. */
  551. public static int compare(int x, int y) {
  552. return (x < y) ? -1 : ((x == y) ? 0 : 1);
  553. }
  554. /**
  555. * 静态常量SIZE用来表四二进制补码形式的int值的比特数,值为32
  556. */
  557. public static final int SIZE = 32;
  558. /**
  559. * 返回在二进制情况下,i的最高位为1,其他全为0的值。
  560. * 将31位都置为1,然后将该值减去该值右移一位的值
  561. * @param i
  562. * @return int
  563. */
  564. public static int highestOneBit(int i) {
  565. //右移一位或上原值
  566. i |= (i >> 1);
  567. i |= (i >> 2);
  568. i |= (i >> 4);
  569. i |= (i >> 8);
  570. i |= (i >> 16);
  571. //i值减去i右移一位的值
  572. return i - (i >>> 1);
  573. }
  574. /**
  575. * 获取最低位为1,其他位都为0的值
  576. * @param i
  577. * @return int
  578. */
  579. public static int lowestOneBit(int i) {
  580. // 先取负数(对正数的i取反码然后加1),得到的结果和i进行与操作。
  581. return i & -i;
  582. }
  583. /**
  584. * 返回i的二进制从头开始有多少个0
  585. * @param i
  586. * @return int
  587. */
  588. public static int numberOfLeadingZeros(int i) {
  589. //i为0,则有32个0
  590. if (i == 0)
  591. return 32;
  592. int n = 1;
  593. // 使用二分查找(也就是折半查找)思想,看右移16、24、28、30、31位的结果是否为0
  594. if (i >>> 16 == 0) { n += 16; i <<= 16; }
  595. if (i >>> 24 == 0) { n += 8; i <<= 8; }
  596. if (i >>> 28 == 0) { n += 4; i <<= 4; }
  597. if (i >>> 30 == 0) { n += 2; i <<= 2; }
  598. n -= i >>> 31;
  599. return n;
  600. }
  601. /**
  602. * 返回i的二进制从尾开始有多少个0
  603. * 基于二分查找
  604. * @param i
  605. * @return int 返回类型
  606. */
  607. public static int numberOfTrailingZeros(int i) {
  608. int y;
  609. if (i == 0) return 32;
  610. int n = 31;
  611. y = i <<16; if (y != 0) { n = n -16; i = y; }
  612. y = i << 8; if (y != 0) { n = n - 8; i = y; }
  613. y = i << 4; if (y != 0) { n = n - 4; i = y; }
  614. y = i << 2; if (y != 0) { n = n - 2; i = y; }
  615. return n - ((i << 1) >>> 31);
  616. }
  617. /**
  618. * 计算二进制数中1的个数
  619. * @param i
  620. * @return int
  621. */
  622. public static int bitCount(int i) {
  623. // 每两位一组统计看有多少个1
  624. // 0x55555555也就是01010101010101010101010101010101
  625. i = i - ((i >>> 1) & 0x55555555);
  626. // 每四位一组统计看有多少个1
  627. // 0x33333333也就是110011001100110011001100110011
  628. i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
  629. // 每八位的1的个数
  630. // 0x0f0f0f0f也就是00001111000011110000111100001111
  631. i = (i + (i >>> 4)) & 0x0f0f0f0f;
  632. // 每16位
  633. i = i + (i >>> 8);
  634. // 每32位
  635. i = i + (i >>> 16);
  636. // 最终与0x3f进行与运算,得到的结果,就是1的个数
  637. return i & 0x3f;
  638. }
  639. /**
  640. * 返回根据指定的位数循环左移指定的 int 值的二进制补码表示形式而得到的值。
  641. * (位是从左边(即高位)移出,从右边(即低位)再进入)
  642. * 注意,使用负距离的左循环等同于右循环:
  643. * rotateLeft(val, -distance) == rotateRight(val, distance)。
  644. * 还要注意的是,以 32 的任何倍数进行的循环都是无操作指令,
  645. * 因此,即使距离为负,除了最后五位外,
  646. * 其余所有循环距离都可以忽略:
  647. * rotateLeft(val, distance) == rotateLeft(val, distance & 0x1F)。
  648. * @param i
  649. * @param distance
  650. * @return int
  651. */
  652. public static int rotateLeft(int i, int distance) {
  653. return (i << distance) | (i >>> -distance);
  654. }
  655. /**
  656. * 返回根据指定的位数循环右移指定的 int 值的二进制补码表示形式而得到的值。
  657. * (位是从右边(即低位)移出,从左边(即高位)再进入)
  658. * 注意,使用负距离的右循环等同于左循环:
  659. * rotateRight(val, -distance) == rotateLeft(val, distance)。
  660. * 还要注意的是,以 32 的任何倍数进行的循环都是无操作指令,
  661. * 因此,即使距离为负,除了最后五位外,
  662. * 其余所有循环距离都可以忽略:
  663. * rotateRight(val, distance) == rotateRight(val, distance & 0x1F)。
  664. * @param i
  665. * @param distance
  666. * @return int
  667. */
  668. public static int rotateRight(int i, int distance) {
  669. return (i >>> distance) | (i << -distance);
  670. }
  671. /**
  672. * 对i进行反转,反转也就是第1位和第32位对调,第2位和第31位对调等
  673. * @param i
  674. * @return int
  675. */
  676. public static int reverse(int i) {
  677. // 将相邻两位进行对调
  678. i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
  679. // 将相邻四位进行对调
  680. i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
  681. // 将相邻的八位进行对调
  682. i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
  683. // 32位中的中间16对调,最高八位和最低八位对调
  684. i = (i << 24) | ((i & 0xff00) << 8) |
  685. ((i >>> 8) & 0xff00) | (i >>> 24);
  686. return i;
  687. }
  688. /**
  689. * 返回指定 int 值的符号函数。(如果指定值为负,则返回 -1;
  690. * 如果指定值为零,则返回 0;如果指定的值为正,则返回 1。)
  691. * @param i
  692. * @return int
  693. */
  694. public static int signum(int i) {
  695. // HD, Section 2-7
  696. return (i >> 31) | (-i >>> 31);
  697. }
  698. /**
  699. * 返回通过反转指定 int 值的二进制补码表示形式中字节的顺序而获得的值
  700. * @param i
  701. * @return int
  702. */
  703. public static int reverseBytes(int i) {
  704. return ((i >>> 24) ) | // 第1字节
  705. ((i >> 8) & 0xFF00) | // 第2字节
  706. ((i << 8) & 0xFF0000) | // 第3字节
  707. ((i << 24)); // 第4字节
  708. }
  709. // 序列号
  710. private static final long serialVersionUID = 1360826667806852920L;
  711. }

参考

Jdk1.6API

https://blog.csdn.net/tree_ifconfig/article/details/82387579

发表评论

表情:
评论列表 (有 0 条评论,115人围观)

还没有评论,来说两句吧...

相关阅读