Java BitSet学习

一. 位运算

在学习 BitSet 之前,我们先看一下位运算;

下述我们拿 long 来接收位运算的返回值,我们知道 long 为 64 位,8 个字节;

// 1. 右移一位,表示 num / 2;右移 6 位,表示 num / 2^6
// 10000     2^4
// 1000000   2^6
// 111111    2^6 - 1
long a = 64 >> 6;
System.out.println(a);  // 1long b = 63 >> 6;
System.out.println(b);  // 0// 2. 左移一位,表示 num * 2;左移 6 位,表示 num * 2^6
// 如果左移 70 位,超过 64 位会溢出,本质还是左移 6 位,也就是 num * 2^6
long c = 1 << 6;
System.out.println(c);  // 64long d = 1 << 70;
System.out.println(d);  // 64

二. BitSet

1. 创建和初始化

可以通过无参构造器或指定初始容量的构造器创建 BitSet;

BitSet bs = new BitSet();   // 默认初始容量为 64 位
BitSet bs = new BitSet(10); // 指定初始容量为 10 位

BitSet 中是以 long[] 来存储位数的,所以 BitSet 的实际存储容量是以 64 的倍数增长的,因此,即使我们指定了 10 位的初始容量,BitSet 的实际容量也是 64 位;

2. 读取容量和长度

BitSet 提供了 size() 和 length() 来获取其实际存储容量和逻辑长度;

  • size():返回 BitSet 实际存储的位数,该值是 64 位的倍数;
  • length():返回 BitSet 中最高设置位的索引加 1,这表示逻辑上的长度;
BitSet bs = new BitSet(10);
int size = bs.size();
System.out.println("size = " + size);      // size = 64
int length = bs.length();
System.out.println("length = " + length);  // length = 0bs.set(1);
bs.set(3);
bs.set(5);
bs.set(7, false);
length = bs.length();
System.out.println("length = " + length);  // length = 6

3. 设置和清除位

BitSet 中提供了很多方法来设置和清除位,包括 set() 和 clear();

BitSet bs = new BitSet();
bs.set(2);                  // 将第 2 位设为 true
bs.clear(2);                // 将第 2 位设为 false
bs.set(3, false);           // 将第 3 位设为 false// 可以通过传递范围参数来批量设置或清除位,左闭右开
bs.set(0, 5);               // 将第 0 到第 4 位设为 true
bs.clear(0, 5);             // 将第 0 到第 4 位设为 false

4. 检查位状态

可以通过 get(int index) 来检查指定位的状态;

BitSet bitSet = new BitSet();bitSet.set(0, true);
bitSet.set(1);
bitSet.set(2, false);System.out.println(bitSet.get(1));    // true
System.out.println(bitSet.get(2));    // false

5. 其他常用方法

  1. isEmpty():判断 BitSet 是否为空;
  2. cardinality():获取 BitSet 中设置为 true 的位的数量;
  3. toString():将 BitSet 转换为字符串输出,只输出 true 的位;
BitSet bitSet = new BitSet();bitSet.set(0, true);
bitSet.set(1);
bitSet.set(2, false);System.out.println(bitSet.isEmpty());       // false
System.out.println(bitSet.cardinality());   // 2
System.out.println(bitSet.toString());      // {0, 1}

6. 遍历

6.1 遍历1位

BitSet 的 stream() 会返回一个 stream 流,其中包含了所有被设置为 1 的位的索引;

BitSet bitSet = new BitSet();bitSet.set(1);
bitSet.set(3);
bitSet.set(7);bitSet.stream().boxed().forEach(item -> System.out.println(item));  // 1 3 7

6.2 遍历0位

BitSet 的 nextClearBit(int index) 会返回大于或等于给定索引的第一个未设置位的位置;

BitSet 中没有现有的 api 轮询设置位为 0 的位的索引,需要结合 nextClearBit();

BitSet bitSet = new BitSet();bitSet.set(1);
bitSet.set(3);
bitSet.set(7);for (int i = bitSet.nextClearBit(0); i < bitSet.size(); i = bitSet.nextClearBit(i+1)) {System.out.println(i);
}

三. 源码分析

我们对几个比较常用的方法进行源码分析;

1. 构造方法

举个例子,如果 nbits 为 64,wordIndex(64-1) + 1 = 1;

如果 nbits 为 65,wordIndex(65-1) + 1 = 2;

// -------------------------------- BitSet ---------------------------------
public BitSet(int nbits) {if (nbits < 0)throw new NegativeArraySizeException("nbits < 0: " + nbits);// 初始化 long words[] 数组initWords(nbits);sizeIsSticky = true;
}// -------------------------------- BitSet ---------------------------------
private void initWords(int nbits) {// wordIndex(nbits-1) 计算 long words[] 数组的初始化大小words = new long[wordIndex(nbits-1) + 1];
}// -------------------------------- BitSet ---------------------------------
private static int wordIndex(int bitIndex) {// 计算 bitIndex 需要的数组大小// 其实就是 bitIndex 右移 6 位,也就是 bitIndex / 2^6return bitIndex >> 6;
}

2. set()

// -------------------------------- BitSet ---------------------------------
public void set(int bitIndex) {if (bitIndex < 0)throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);// 1. 计算在 words[] 中的下标int wordIndex = wordIndex(bitIndex);expandTo(wordIndex);// 2. 作或运算// 如果 bitIndex = 70,wordIndex = 1,1 << 70 = 1000000words[wordIndex] |= (1L << bitIndex);checkInvariants();
}

3. get()

// -------------------------------- BitSet ---------------------------------
public boolean get(int bitIndex) {if (bitIndex < 0)throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);checkInvariants();// 1. 计算在 words[] 中的下标int wordIndex = wordIndex(bitIndex);// 2. 不能超出 wordsInUse,作与运算return (wordIndex < wordsInUse)&& ((words[wordIndex] & (1L << bitIndex)) != 0);
}

4. size()

// -------------------------------- BitSet ---------------------------------
public int size() {// long words[] 数组的长度 * 64,其实就是得到位的长度return words.length * 64;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/47484.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ | Leetcode C++题解之第273题整数转换英文表示

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<string> singles {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Ni…

DC-1靶场打靶第一次!!!!冲冲冲!

今天打了一下DC-1这个靶场&#xff0c;感觉收获比大&#xff0c;我就来记录一下。 我的思路是下面的这个 我们先把靶机导入&#xff0c;然后与我们的liunx(攻击机)在同一个网段中&#xff0c;这也大大的减低难度。 然后我们先对自己这个网段内存活的主机进行操作&#xff0c;我…

【Spring Boot】网页五子棋项目中遇到的困难及解决方法

目录 一、HikariPool-1 - Starting异常二、Invalid bound statement (not found)异常三、The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary异常四、The server time zone value时区报错异常五、补充知识点…

免费【2024】springboot 白优校园社团网站的设计与实现

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

Django transaction.atomic()事务处理

在Django中&#xff0c;transaction.atomic()是一个上下文管理器&#xff0c;它会自动开始一个事务&#xff0c;并在代码块执行完毕后提交事务。如果在代码块中抛出异常&#xff0c;事务将被自动回滚&#xff0c;确保数据库的一致性和完整性。 在实际应用中&#xff0c;你可能需…

PHP 表单验证:邮件和URL

PHP 表单验证&#xff1a;邮件和URL 在Web开发中&#xff0c;表单验证是一个至关重要的环节&#xff0c;它确保了用户输入的数据的有效性和安全性。特别是在处理邮件地址和URL时&#xff0c;准确的验证尤为重要。本文将详细介绍如何使用PHP来验证表单中的邮件地址和URL。 邮件…

[HTML]一文掌握

背景知识 主流浏览器 浏览器是展示和运行网页的平台&#xff0c; 常见的五大浏览器有 IE浏览器、火狐浏览器&#xff08;Firefox&#xff09;、谷歌浏览器&#xff08;Chrome&#xff09;、Safari浏览器、欧朋浏览器&#xff08;Opera&#xff09; 渲染引擎 浏览器解析代码渲…

R语言读取txt和csv只有1列时

多半是间隔符的问题 ?read.table read.table(file, header FALSE, sep "", quote "\"",dec ".", numerals c("allow.loss", "warn.loss", "no.loss"),row.names, col.names, as.is !stringsAsFacto…

Agent类型解析:AIGC在不同领域的应用与影响

目录 引言 垂直智能体&#xff08;Vertical Agent&#xff09; 水平智能体&#xff08;Horizontal Agent&#xff09; 混合智能体&#xff08;Hybrid Agent&#xff09; 结论 引言 在人工智能&#xff08;AI&#xff09;领域&#xff0c;智能体&#xff08;Agent&#xf…

Edge浏览器加载ActiveX控件

背景介绍 新版Edge浏览器也是采用Chromium内核&#xff0c;虽然没有谷歌浏览器市场占有率高&#xff0c;但是依托微软操作系统的优势&#xff0c;Edge浏览器还是发展很强劲&#xff0c;占据着市场第二的位置。随着微软停止服务IE浏览器&#xff0c;曾经风光无限的IE浏览器页退出…

如何使用javascript将商品添加到购物车?

使用JavaScript将商品添加到购物车可以通过以下步骤实现&#xff1a; 创建一个购物车对象&#xff0c;可以是一个数组或者对象&#xff0c;用于存储添加的商品信息。在网页中的商品列表或详情页面&#xff0c;为每个商品添加一个“添加到购物车”的按钮&#xff0c;并为按钮绑…

甄选范文“论企业集成平台的理解与应用”,软考高级论文,系统架构设计师论文

论文真题 企业集成平台(Enterprise Imtcgation Plaform,EIP)是支特企业信息集成的像环境,其主要功能是为企业中的数据、系统和应用等多种对象的协同行提供各种公共服务及运行时的支撑环境。企业集成平台能够根据业务模型的变化快速地进行信息系统的配置和调整,保证不同系统…

bootstrap设置表格列宽及换行

bootstrap设置表格列宽及换行 业务背景页面操作问题处理 业务背景 在日常工作过程中&#xff0c;遇到一个字段长度太长的时候&#xff0c;列表展示整个展示的话效果太差&#xff0c;比如这样的 列表展示出现了滚动条&#xff0c;查看列表内容时就不太方便&#xff1b;但是业务…

数学建模--优劣解距离法TOPSIS

目录 简介 TOPSIS法的基本步骤 延伸 优劣解距离法&#xff08;TOPSIS&#xff09;的历史发展和应用领域有哪些&#xff1f; 历史发展 应用领域 如何准确计算TOPSIS中的理想解&#xff08;PIS&#xff09;和负理想解&#xff08;NIS&#xff09;&#xff1f; TOPSIS方法在…

前端面试题汇总2

1. CSS 中两个 .class1 .class2 从哪个开始解析 在 CSS 中&#xff0c;选择器 .class1 .class2 表示所有 class 为 class1 的元素中的 class 为 class2 的子元素。浏览器解析这个选择器时&#xff0c;从右向左解析。也就是说&#xff0c;浏览器首先找到所有 class 为 class2 的…

【Node.js基础04】node.js模块化

一&#xff1a;什么是模块化 在Node.js中&#xff0c;每个文件都可视为一个独立的模块。模块化提高了代码的复用性&#xff0c;按需加载&#xff0c;具有独立的作用域 二&#xff1a;如何实现多个文件间导入和导出 1 CommonJS标准&#xff08;默认&#xff09;-导入和导出 …

Logstash docker发布

一 下载Logstash 不废话了&#xff0c;我下载的7.17.6 二 新增配置文件 在logstash/pipeline中&#xff0c;添加logstash.conf input {jdbc { # 连接jdbc_connection_string > "jdbc:mysql://192.168.1.1:3306/kintech-cloud-bo&#xff1f;characterEncodingUTF-8&…

大学生电子设计竞赛中的自动化测试与测量技术(内附资料)

大学生电子设计竞赛是一个技术密集型的竞赛&#xff0c;它要求参赛者在有限的时间内完成一个既定的电子系统设计。自动化测试与测量技术在这一过程中扮演着至关重要的角色&#xff0c;它不仅可以提高测试效率&#xff0c;还可以增加测量的准确性和重复性。本文将探讨自动化测试…

汽车电动空调系统

1.电动空调系统概述 电动汽车制冷空调系统与传统汽车制冷空调系统基本原理一样&#xff0c;区别在于电动汽车空调系统采用电动空调压缩机。电动空调压缩机由驱动电机&#xff0c;压缩机&#xff0c;控制器集成。 电动空调压缩机的驱动电机采用体积小&#xff0c;质量轻&#x…

初学者简单了解爬虫的基本认识和操作(详细参考图片)

爬虫 定义&#xff1a;爬虫&#xff08;Web Crawler 或 Spider&#xff09;是一种自动访问互联网上网页的程序&#xff0c;其主要目的是索引网页内容&#xff0c;以便搜索引擎能够快速检索到相关信息。以下是爬虫的一些关键特性和功能&#xff1a; 自动化访问&#xff1a;爬虫能…