讲师中心 微信公众号
AI工具推荐 视频效率加速

在Java中BitSet如何进行位操作_Java位运算工具类解析

冬伟酱_2464

冬伟酱_2464

发布时间:2026-02-04 12:30:15

|

968人浏览过

|

来源于php中文网

原创

BitSet的and/or/xor是集合运算而非CPU位指令,修改原对象;clear/set负索引抛IndexOutOfBoundsException;遍历用nextSetBit;toByteArray()为big-endian,跨语言需注意字节序;字段级操作宜用BitField。

在java中bitset如何进行位操作_java位运算工具类解析

BitSet 的 and/or/xor 操作不是直接位运算,而是集合运算

很多人以为 BitSet.and() 是对两个 BitSet 的二进制表示做按位与,其实它是集合交集操作:结果中第 i 位为 true 当且仅当两个 BitSet 的第 i 位都为 true。这在语义上等价于按位与,但底层不走 CPU 位指令,而是分块(long 数组)循环处理。

实际使用时要注意:两个 BitSet 长度不同时,短的那个“高位补 false”,不会越界或抛异常。比如:

BitSet a = new BitSet(); a.set(0); a.set(3); // 二进制 ...0001001
BitSet b = new BitSet(); b.set(0); b.set(1); // 二进制 ...0000011
a.and(b); // 结果只有 bit 0 为 true → {...0000001}
  • and()、or()、xor() 都会**修改调用方对象**,不是返回新 BitSet
  • 如需不可变行为,得先 (BitSet) a.clone() 再操作
  • 如果只读场景多,考虑用 ImmutableBitSet(Guava)或自行封装只读包装

clear() 和 set() 的索引边界容易误判

BitSet.clear(int index) 和 set(int index) 在 index 超出当前容量时,会自动扩容;但若传入负数,会直接抛 IndexOutOfBoundsException —— 这点和数组不同(数组抛 ArrayIndexOutOfBoundsException),容易在日志里漏看异常类型。

更隐蔽的问题是:BitSet 的“逻辑长度”不等于“已设置的最高位索引 + 1”。它没有 length() 方法返回有效位数,只有 size() 返回内部 long 数组容量(单位是 long,不是 bit),而 length() 返回的是“最高位索引 + 1”(即“逻辑位数”)。

立即学习“Java免费学习笔记(深入)”;

JavaStoryDevelop
JavaStoryDevelop

你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在

下载
  • 判断是否全空,用 isEmpty(),别用 cardinality() == 0(虽等价但稍慢)
  • 遍历所有置位位置,优先用 nextSetBit(0) 循环,别 for (int i = 0; i length() 可能远大于实际活跃位数
  • 清空指定范围,用 clear(from, to)(to 不包含),注意 from > to 会静默忽略,不报错

BitSet 与 int/long 互转要小心高低位顺序

BitSet 本身不规定字节序,其内部以 long 数组存储,低位 bit 存在 long 的最低位(LSB)。所以把 int 转成 BitSet 时,bit 0 对应 int 的最低位:

BitSet bs = BitSet.valueOf(new long[]{5L}); // 5 = 0b101 → bit 0 和 bit 2 为 true
System.out.println(bs.nextSetBit(0)); // 0
System.out.println(bs.nextSetBit(1)); // 2

反过来,BitSet.toByteArray() 返回的是 **big-endian 字节数组**,且只保留“有意义”的字节(高位全 0 的字节会被截掉),而 BitSet.toLongArray() 返回的是原始 long 块,含可能的高位 0 long。

  • 跨系统序列化 BitSet 时,不要直接用 toByteArray() 传给 C/C++ 等按小端解析的代码
  • 想还原为某个固定宽度整数(如 32 位 int),得手动取前 4 字节再反转字节序,或用 ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getInt()
  • BitSet.valueOf(byte[]) 默认按 big-endian 解释,且字节数组索引 0 是最高位所在字节

替代方案:Apache Commons Lang 的 BitField 更适合字段级操作

如果目标不是大位图管理,而是像解析协议头、提取标志位(flag)、读写结构体中的 bit 字段,BitSet 就太重了——它没提供“从第 n 位起取 m 位”这种操作。

这时候 org.apache.commons.lang3.BitField 更贴切:它专注单个整数内的位字段定位和掩码计算,例如:

BitField versionField = new BitField(0x0000000F); // 低 4 位
int header = 0x12345678;
int version = versionField.getValue(header); // 提取低 4 位值
  • BitField 是无状态工具类,线程安全,适合做常量定义
  • 它不维护位状态,只做掩码和位移,性能接近原生位运算
  • 若需运行时动态定义字段宽度,还是得手写 (value >> offset) & ((1

BitSet 的真正优势在于稀疏大位图(百万级 bit 中只有几百个 true)、支持动态 resize 和高效集合运算;拿它做 32 位寄存器解析,反而绕路又难 debug。

热门AI工具

更多
AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

相关专题

更多
guava包作用
guava包作用

guava是一个java库,增强了java标准库,提供更有效率和易于使用的集合、实用程序、缓存和并发工具。想了解更多guava的相关内容,可以阅读本专题下面的文章。

5251

2024.05.29

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6084

2023.10.24

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

4774

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

4911

2025.07.04

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6439

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3145

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

4028

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2785

2025.08.29

Playwright 测试失败怎么办
Playwright 测试失败怎么办

Playwright测试失败专题汇集超时、定位器匹配、浏览器提前关闭、依赖与插件配置、文件上传、SSL及Docker启动等故障文章,并介绍通过截图、报告和Trace定位错误。

0

2026.10.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn