最经典高效的方法是使用 n & (n - 1) 位运算技巧,每次消除最低位的 1,时间复杂度 o(k),k 为二进制中 1 的个数;该法对正负数均适用,无需额外处理补码。

Java 中快速计算一个整数二进制中 1 的个数,最经典高效的方法是使用位运算中的 n & (n - 1) 技巧,它每次能消除最低位的 1。时间复杂度为 O(k),k 是二进制中 1 的个数,比遍历 32 位更优。
利用 n & (n - 1) 清除最低位的 1
原理:对任意正整数 n,n & (n - 1) 的结果会把 n 的二进制表示中最右边的 1 变成 0,其余位不变。例如:
- n = 12(二进制 1100),n - 1 = 11(1011),n & (n - 1) = 1000(即 8),消除了最右的 1
- 重复该操作,直到 n 变为 0,操作次数就是 1 的个数
代码示例:
int count = 0;
while (n != 0) {
count++;
n = n & (n - 1); // 关键:每次去掉一个 1
}
return count;
}
处理负数:Java 中的补码不影响该方法
Java 中 int 是 32 位补码表示,负数的最高位为 1。但 n & (n - 1) 在补码下依然有效——它仍能正确清除最右侧的 1(包括符号位)。例如:
- n = -1(32 个 1),第一次 n & (n - 1) 得到 -2(31 个 1),依此类推,共执行 32 次后归零
- 无需额外转换为无符号或用 long,原生 int 即可安全使用
其他位运算技巧(补充)
虽然不如 n & (n - 1) 简洁,但以下方法也常见:
-
无符号右移 + 与 1 判断:用
n & 1检查末位,再n >>>= 1(注意用>>而非>>,避免负数补 1) -
分治法(Brian Kernighan 扩展):如 Java 内置
Integer.bitCount()实际采用的算法,通过多步掩码与移位合并统计(如 `(n & 0x55555555) + ((n >>> 1) & 0x55555555)`),适合批量高性能场景
日常开发推荐首选 n & (n - 1) 法——逻辑清晰、代码短、效率高、兼容正负零。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











