核心一句话Integer.rotateRight(i, distance) 将指定 int 值的二进制表示向右循环移动(循环右移)指定的位数,最高位移出后补到最低位,常用于位运算、哈希函数、加密算法等高性能场景。


一、方法定义

public static int rotateRight(int i, int distance)
  • 所属类java.lang.Integer
  • 访问类型public static
  • 参数
    • i:要循环右移的 int 值(32位)
    • distance:移动的位数(可以是任意整数,超出范围会自动取模)
  • 返回值:循环右移后的 int
  • 异常:无

⚠️ 注意distance 会被自动对 32 取模(distance % 32),因此 rotateRight(i, 33) 等价于 rotateRight(i, 1)


二、功能说明

什么是“循环右移”(Rotate Right)?

  • 普通右移(>>):高位补符号位(正数补0,负数补1),低位移出丢弃。
  • 循环右移高位移出的部分,补到低位,形成“循环”。

示例(4位简化版):

原始: 1011
右移1位(普通): 1101(补符号位,假设为负)
循环右移1位:   1101 → 但实际是:1011 → [1]101 → 1101(高位1移到低位)

在 32 位中:

i = 0x80000001  → 二进制:10000000 00000000 00000000 00000001
rotateRight(i, 1) → 11000000 00000000 00000000 00000000 → 0xC0000000

三、底层原理与行为分析

✅ 循环右移的等价操作:

// rotateRight(i, n) 等价于:
(i >>> n) | (i << (32 - n))
  • i >>> n:无符号右移 n 位,高位补0
  • i << (32 - n):左移 32-n 位,低位补0
  • |:按位或,将移出的高位“拼接”回低位

💡 JVM 通常会将其优化为单条 CPU 指令(如 x86 的 ROR 指令)。

distance 自动取模:

rotateRight(i, 35) == rotateRight(i, 3)  // 因为 35 % 32 = 3
rotateRight(i, -1) == rotateRight(i, 31) // 负数等价于左移

四、示例代码

✅ 示例 1:基本使用

int i = 0x80000001; // 二进制: 1000...0001
System.out.printf("%08x%n", i);                    // 80000001

int rotated = Integer.rotateRight(i, 1);
System.out.printf("%08x%n", rotated);              // c0000000
// 解释:最高位 1 移到最低位,原最低位 1 被挤出 → 新值:1100...0000

✅ 示例 2:小数值循环右移

int a = 0b1000_0000_0000_0000_0000_0000_0000_0001; // 0x80000001
int b = Integer.rotateRight(a, 1);
System.out.println(Integer.toBinaryString(b));
// 输出:11000000000000000000000000000000

✅ 示例 3:distance 超出范围

int x = 1;
System.out.println(Integer.rotateRight(x, 32)); // 1(32%32=0,不移动)
System.out.println(Integer.rotateRight(x, 33)); // 2(等价于右移1位:1 → 10 → 2)
System.out.println(Integer.rotateRight(x, -1)); // 1073741824(等价于左移31位)

✅ 示例 4:验证等价公式

int i = 0x80000001;
int n = 1;
int expected = (i >>> n) | (i << (32 - n));
int actual = Integer.rotateRight(i, n);
System.out.println(expected == actual); // true

五、使用技巧

🔧 技巧 1:实现循环左移(rotateLeft)

public static int rotateLeft(int i, int distance) {
    return Integer.rotateRight(i, -distance);
    // 或:return (i << distance) | (i >>> (32 - distance));
}

🔧 技巧 2:在哈希函数中使用(如 HashMap 扰动函数)

// JDK 1.8 HashMap 中的 hash 扰动函数(简化版思想)
static int hash(int h) {
    return h ^ Integer.rotateRight(h, 16);
    // 实际是 h ^ (h >>> 16),但 rotate 可用于更复杂扰动
}

🔧 技巧 3:生成伪随机位模式

int seed = 0x12345678;
for (int i = 0; i < 10; i++) {
    seed = Integer.rotateRight(seed, 7) ^ i;
    System.out.printf("%08x%n", seed);
}

🔧 技巧 4:位反转辅助(结合其他操作)

// 循环移位可用于位反转算法的中间步骤

六、常见用途(实际场景)

场景 说明
哈希函数设计 如 MurmurHash、xxHash 中使用循环移位扰动输入
加密算法 AES、SHA 等算法中常用循环移位混淆数据
伪随机数生成 作为 PRNG 的一部分,增加随机性
位操作算法 位反转、位扫描、数据压缩等
游戏开发 随机地图生成、状态混淆

七、注意事项 ⚠️

注意点 说明
静态方法 直接调用,无需实例
⚠️ distance 自动取模 32 rotateRight(i, 35) 等价于 rotateRight(i, 3)
⚠️ 负 distance 等价于左移 rotateRight(i, -1) = rotateLeft(i, 1)
性能极高 JVM 通常映射为 CPU 的 ROR 指令
⚠️ 无符号移位参与 内部使用 >>> 保证高位补0
不可变性 不修改原值,返回新值

八、最佳实践 ✅

  1. 用于高性能位操作场景,如哈希、加密、算法竞赛。
  2. 替代手动位拼接,代码更简洁、安全。
  3. 理解其与 >>>>> 的区别:循环 vs 丢弃。
  4. 结合 rotateLeftreversebitCount 构建位工具类
  5. 在阅读 JDK 源码(如 SplittableRandom)时识别其用途

九、性能优化建议

场景 建议
单次调用 性能极高,接近硬件指令
高频调用 可放心使用,JVM 会内联优化
替代方案 手动 (i >>> n) | (i << (32-n)) 效果相同,但可读性差
JVM 优化 HotSpot 会将其编译为 ROR 汇编指令,速度极快

💡 在支持 ROR 指令的 CPU 上,执行时间通常为 1~2 个时钟周期


十、与其他方法对比

方法 作用 是否循环
i >> n 有符号右移
i >>> n 无符号右移
Integer.rotateRight(i, n) 循环右移
Integer.rotateLeft(i, n) 循环左移 ✅(可用 rotateRight(i, -n) 实现)

十一、总结:快速掌握要点 ✅

项目 内容
核心功能 int 二进制循环右移指定位数
关键特性 移出的高位补到低位,形成“循环”
distance 处理 自动对 32 取模,负数等价于左移
性能 ⭐⭐⭐⭐⭐(接近 CPU 指令速度)
常见用途 哈希、加密、PRNG、位算法
等价操作 (i >>> n) | (i << (32 - n))
最佳实践 用于高性能位操作,替代手动拼接

🎯 一句话总结:

Integer.rotateRight() 是一个高性能的位循环操作工具,将整数的二进制位向右循环移动,移出的高位自动补到低位,广泛应用于哈希、加密和算法优化中,是 Java 位运算的“高级武器”。