核心一句话:
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
位,高位补0i << (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 |
✅ 不可变性 | 不修改原值,返回新值 |
八、最佳实践 ✅
- ✅ 用于高性能位操作场景,如哈希、加密、算法竞赛。
- ✅ 替代手动位拼接,代码更简洁、安全。
- ✅ 理解其与
>>
、>>>
的区别:循环 vs 丢弃。 - ✅ 结合
rotateLeft
、reverse
、bitCount
构建位工具类。 - ✅ 在阅读 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 位运算的“高级武器”。