Integer.bitCount()
是 Java 中用于计算一个整数的二进制表示中“1”的个数(即 Hamming Weight 或 Population Count)的高效静态方法。它在算法优化、位运算、密码学、数据压缩等领域有广泛应用。
一、方法定义
public static int bitCount(int i)
- 所属类:
java.lang.Integer
- 访问修饰符:
public static
- 参数:
int i
—— 要计算的整数(支持负数) - 返回值:该整数二进制表示中
1
的个数(int
类型) - 异常:无异常抛出
✅ 该方法对正数和负数均有效,因为它直接操作整数的 32 位补码表示。
二、功能说明
计算一个 int
类型数值的 二进制形式中 1 的个数。
- 正数:按其二进制表示计算。
- 负数:按其 32 位补码 形式计算(结果仍是有效计数)。
📌 别名:
- Hamming Weight
- Population Count (popcount)
三、示例代码
示例 1:基本用法(正数)
int num = 7; // 二进制: 00000000 00000000 00000000 00000111
int count = Integer.bitCount(num);
System.out.println(count); // 输出:3
示例 2:不同数值的位数统计
System.out.println(Integer.bitCount(0)); // 0 → 0 个 1
System.out.println(Integer.bitCount(1)); // 1 → 1 个 1
System.out.println(Integer.bitCount(2)); // 10 → 1 个 1
System.out.println(Integer.bitCount(3)); // 11 → 2 个 1
System.out.println(Integer.bitCount(15)); // 1111 → 4 个 1
System.out.println(Integer.bitCount(255)); // 11111111 → 8 个 1
示例 3:负数处理(关键!)
int negative = -1;
// -1 的补码:32 个 1 → 11111111 11111111 11111111 11111111
System.out.println(Integer.bitCount(-1)); // 输出:32
System.out.println(Integer.bitCount(-2)); // 输出:31
// -2 补码: 111...110 → 31 个 1
示例 4:2 的幂次方
// 2 的幂次方二进制只有一个 1
System.out.println(Integer.bitCount(8)); // 1000 → 输出:1
System.out.println(Integer.bitCount(16)); // 10000 → 输出:1
System.out.println(Integer.bitCount(1024)); // 10000000000 → 输出:1
四、使用技巧
1. 判断是否为 2 的幂次方
一个正整数是 2 的幂次方,当且仅当 bitCount(n) == 1
public static boolean isPowerOfTwo(int n) {
return n > 0 && Integer.bitCount(n) == 1;
}
System.out.println(isPowerOfTwo(8)); // true
System.out.println(isPowerOfTwo(10)); // false
2. 计算两个数的汉明距离(Hamming Distance)
汉明距离 = 两数异或后 bitCount
的结果
int x = 1; // 01
int y = 4; // 100
int distance = Integer.bitCount(x ^ y); // 101 → 2 个 1
System.out.println(distance); // 输出:2
3. 统计集合中元素个数(位图场景)
用 int
的每一位表示一个布尔状态(如权限、选项)
int flags = 0b101101; // 表示第 0,2,3,5 位被选中
int selectedCount = Integer.bitCount(flags);
System.out.println("选中项数量: " + selectedCount); // 输出:4
4. 奇偶校验位计算
boolean hasEvenParity = (Integer.bitCount(data) % 2) == 0;
五、常见错误与注意事项
问题 | 说明 | 建议 |
---|---|---|
误解负数结果 | 认为 -1 的 bitCount 应为 1,实际是 32 |
理解其基于 32 位补码 |
忽略符号位影响 | 负数高位全是 1,导致 1 的数量很多 |
在业务逻辑中根据需求处理 |
性能误解 | 认为它是简单循环,实际是高度优化的算法 | 可放心在高频场景使用 |
六、底层实现原理(简化版)
Integer.bitCount()
使用了 分治法 + 位并行运算,避免逐位判断,性能极高。
以下是其核心思想的简化版本:
public static int bitCount(int i) {
// 将每 2 位一组,统计 1 的个数
i = i - ((i >>> 1) & 0x55555555);
// 每 4 位合并
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
// 每 8 位合并
i = (i + (i >>> 4)) & 0x0f0f0f0f;
// 累加到高 8 位
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
✅ 时间复杂度:O(1),仅需常数次位运算。
七、与其他方法对比
方法 | 功能 | 性能 | 适用场景 |
---|---|---|---|
Integer.bitCount(i) |
计算 1 的个数 | ⭐⭐⭐⭐⭐ (极快) | 推荐首选 |
手动循环移位 | while(i!=0) { count += i&1; i>>>=1; } |
⭐⭐ (慢) | 教学理解 |
Integer.toBinaryString(i).replace("0", "").length() |
字符串方式 | ⭐ (极慢) | 不推荐 |
✅ 结论:永远优先使用
bitCount()
,不要手动实现。
八、最佳实践
✅ 推荐做法
用于算法题中的位统计
// LeetCode 常见题型 int count = Integer.bitCount(n);
性能敏感场景(如游戏、高频交易)
- 位图压缩、状态机、权限校验等
结合位运算进行逻辑判断
if (Integer.bitCount(options) >= 3) { // 至少选择了 3 个选项 }
与
Integer.numberOfLeadingZeros()
配合使用int highestBitPos = 31 - Integer.numberOfLeadingZeros(n); int ones = Integer.bitCount(n);
九、性能分析
- 时间复杂度:O(1),固定步数完成
- JVM 优化:现代 JVM 会将其优化为单条 CPU 指令(如 x86 的
POPCNT
) - 性能极高:远快于任何手动循环或字符串操作
✅ 在 JDK 源码中被广泛用于 HashMap
、BitSet
等核心类。
十、总结
项目 | 内容 |
---|---|
核心功能 | 计算 int 二进制中 1 的个数(Hamming Weight) |
支持负数 | ✅ 基于 32 位补码计算 |
返回值 | int ,范围 0~32 |
典型用途 | 位运算、算法优化、数据压缩、权限统计 |
性能 | ⭐⭐⭐⭐⭐ 极高,推荐首选 |
最佳实践 | 用于判断 2 的幂、汉明距离、集合大小等 |
常见误区 | 期望负数返回小值,实际是补码计数 |
💡 一句话总结:
Integer.bitCount()
是 Java 中最高效的“1 的个数”计算方法,基于位并行算法实现,适用于所有整数(含负数),是位运算编程的必备工具。