Integer.bitCount()是Java中O(1)时间复杂度的内置方法,底层通过JVM intrinsic优化为CPU的popcnt指令,比手动循环或位运算更快,支持正负数及零的补码统计,无需装箱拆箱。

Java 中直接用 Integer.bitCount(int i) 就是最高效的方式——它底层调用的是 JVM 内置的 CPU 指令(如 x86 的 popcnt),时间复杂度 O(1),比手动循环或位运算技巧快得多。
为什么 Integer.bitCount 比自己写更快
该方法不是纯 Java 实现,而是 HotSpot JVM 对 java.lang.Integer.bitCount 的 intrinsic 优化。JIT 编译时会将其替换为单条硬件指令(前提是 CPU 支持 POPCNT 指令,现代 Intel/AMD 大多支持)。自己用 while 循环或 Brian Kernighan 算法,哪怕再精简,也要执行多次分支和位操作,性能差距明显。
- 不依赖 JDK 版本(JDK 1.5+ 全支持)
- 对正数、负数、零都正确(按补码计算 1 的个数)
- 无副作用、线程安全、无需额外对象创建
包装类怎么用?注意自动拆箱即可
Integer 是引用类型,但 bitCount 是静态方法,只接受 int 基本类型参数。使用包装类时,JVM 会自动拆箱:
Integer num = 15; // 二进制 1111 → 4 个 1 int count = Integer.bitCount(num); // 自动调用 num.intValue()
无需手动调用 num.intValue(),也不建议先转成字符串再统计——那样既慢又占内存。
立即学习“Java免费学习笔记(深入)”;
常见误用提醒
别在循环里反复装箱/拆箱;也别误以为它支持 long 或其他类型:
- 要算 long:用
Long.bitCount(long l) - 要算 byte/short:先隐式提升为 int,再调用
Integer.bitCount((int) b) - 避免这样写:
new Integer(42).bitCount()—— 方法是 static 的,不能通过实例调用
对比一下实际性能(示意)
对一亿次计算 0x55555555(16 个 1):
-
Integer.bitCount(x):约 80–120 ms(取决于 CPU 和 JIT 状态) - Brian Kernighan(n & (n−1) 循环):约 300–500 ms
- 朴素右移计数:约 600–900 ms
差距主要来自指令级优化和分支预测效率。


















