BitMap解析(一)

文章目录

  • 前言
  • 数据结构
    • 添加与删除操作
  • JDK中BitSet源码解析
    • 重要成员属性
    • 初始化
    • 添加数据
    • 清除数据
    • 获取数据
    • size和length方法
    • 集合操作:与、或、异或

前言

为什么称为bitmap?
bitmap不仅仅存储介质以及数据结构不同于hashmap,存储的key和value也不同。

bitmap的key是元素的index,value只有0或者1(具体结构见下文)。

数据结构

Bit-map的基本思想就是用一个bit位来标记某个元素对应的Value,而Key即是该元素。由于采用了Bit为单位来存储数据,因此可以很大程度上节省存储空间。

举例:
bitmap
key-value: bitmap[1] = 1、bitmap[2]=0

添加与删除操作

添加:使用1和key所在位的value进行 |(或)

删除:使用1和key所在位的value进行 &(与)

JDK中BitSet源码解析

位于java.util包中

重要成员属性

/** BitSets are packed into arrays of "words."  Currently a word is* a long, which consists of 64 bits, requiring 6 address bits.* The choice of word size is determined purely by performance concerns.* 采用long作为载体,long有8个byte,所以有一个long有64个bit,64这个数字需要6个bit承载*/
private final static int ADDRESS_BITS_PER_WORD = 6;
// 每一个words里面的元素占有64位
private final static int BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD;
private final static int BIT_INDEX_MASK = BITS_PER_WORD - 1;
/* Used to shift left or right for a partial word mask */
private static final long WORD_MASK = 0xffffffffffffffffL;
/*** @serialField bits long[]** The bits in this BitSet.  The ith bit is stored in bits[i/64] at* bit position i % 64 (where bit position 0 refers to the least* significant bit and 63 refers to the most significant bit).*/
private static final ObjectStreamField[] serialPersistentFields = {new ObjectStreamField("bits", long[].class),
};
/*** The internal field corresponding to the serialField "bits".* bitset的数据载体*/
private long[] words;
/*** The number of words in the logical size of this BitSet.* 表示数组中最多使用的元素个数,也就是最后一个不为 0 的元素的索引加 1;比如[0,4,0,0],数组长度为 4,但是最后一个不为 0 的元素是 1,所以 wordsInUse = 2*/
private transient int wordsInUse = 0;

初始化

创建一个 BitSet 对象时,默认 words 的长度为 1,并且 words[0] = 0。当然也可以用户给定一个具体的容量大小,如下代码:

/**
* BitSet.class
* 创建一个能存储给定数据索引的 BitSet
*/
public BitSet(int nbits) {// 参数合法性判断if (nbits < 0)throw new NegativeArraySizeException("nbits < 0: " + nbits);// 调用 initWords 方法初始化initWords(nbits);sizeIsSticky = true;
}private void initWords(int nbits) {words = new long[wordIndex(nbits-1) + 1];
}
// 得到 bitIndex 对应的 words 下标
private static int wordIndex(int bitIndex) {return bitIndex >> ADDRESS_BITS_PER_WORD;
}

添加数据

public void set(int bitIndex) {// 参数合法性检验if (bitIndex < 0)throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);// 得到对应的数组下标int wordIndex = wordIndex(bitIndex);// 是否要扩容expandTo(wordIndex);// 修改数据words[wordIndex] |= (1L << bitIndex); // 参数检查checkInvariants();
}
private void expandTo(int wordIndex) {int wordsRequired = wordIndex+1;if (wordsInUse < wordsRequired) {// 扩容ensureCapacity(wordsRequired);wordsInUse = wordsRequired;}
}
private void ensureCapacity(int wordsRequired) {if (words.length < wordsRequired) {// Allocate larger of doubled size or required size// 基本上是扩容两倍int request = Math.max(2 * words.length, wordsRequired);words = Arrays.copyOf(words, request);sizeIsSticky = false;}}

注意这里的set(bitIndex)是让二进制的位置为1,并不是让words数组的某一index为1.
扩容的逻辑是:如果需要的长度大于数组的两倍,则扩容到需要的长度。否则,扩容位数组的两倍。

清除数据

public void clear(int bitIndex) {//...int wordIndex = wordIndex(bitIndex);// 如果 wordIndex >= wordsInUse,说明该索引要么不存在,要么一定是 0 ,直接返回即可if (wordIndex >= wordsInUse)return;words[wordIndex] &= ~(1L << bitIndex);recalculateWordsInUse();//...
}
// 修改完可能会引起 wordsInUse 的变化,所以还要调用 recalculateWordsInUse() 重新计算 wordsInUse:从后往前遍历直到遇到 words[i] != 0,修改 wordsInUse = i+1。
private void recalculateWordsInUse() {int i;for (i = wordsInUse-1; i >= 0; i--)if (words[i] != 0)break;wordsInUse = i+1; // The new logical size
}

获取数据

public boolean get(int bitIndex) {if (bitIndex < 0)throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);checkInvariants();int wordIndex = wordIndex(bitIndex);return (wordIndex < wordsInUse)&& ((words[wordIndex] & (1L << bitIndex)) != 0);
}

size和length方法

/*** Returns the number of bits of space actually in use by this* {@code BitSet} to represent bit values.* The maximum element in the set is the size - 1st element.** @return the number of bits currently in this bit set*/
public int size() {return words.length * BITS_PER_WORD;
}/*** Returns the "logical size" of this {@code BitSet}: the index of* the highest set bit in the {@code BitSet} plus one. Returns zero* if the {@code BitSet} contains no set bits.* 最高非0位+1** @return the logical size of this {@code BitSet}* @since  1.2*/
public int length() {if (wordsInUse == 0)return 0;return BITS_PER_WORD * (wordsInUse - 1) +(BITS_PER_WORD - Long.numberOfLeadingZeros(words[wordsInUse - 1]));
}
  • size方法:words数组的长度 * 64(每个long的长度)
  • lenght方法:最高位的1所在位置+ 1
    示例:
    示例

集合操作:与、或、异或

集合操作还是很常用的,具体不作说明了,自行去看源码。

本文就到这里,下一篇介绍它的高级应用。

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

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

相关文章

4D激光雷达

什么是4D激光雷达 4D激光雷达,也称为4D成像雷达,是一种利用回声定位和飞行时间测量概念来绘制三维环境中物体并附加速度信息的技术。相比于传统的3D激光雷达,4D激光雷达可以生成点云的3D坐标,并提供关于环境的第四维度信息,通常是速度。这种技术被广泛应用于自动驾驶汽车…

ML:2-2neural network layer

文章目录 1. 神经网络层2. 更复杂的神经网络3. 神经网络的前向传播 【吴恩达机器学习笔记p47-49】 1. 神经网络层 input&#xff1a;4个数字的向量。3个神经元分别做logistic regression。下角标&#xff1a;标识第 i 个神经元的值。上角标&#xff1a;表示第 j 层layer的值。…

打PTA 分数 15

传说这是集美大学的学生对话。本题要求你做一个简单的自动问答机&#xff0c;对任何一个问句&#xff0c;只要其中包含 PTA 就回答 Yes!&#xff0c;其他一概回答 No.。 输入格式&#xff1a; 输入第一行给出一个整型范围内的正整数 N&#xff0c;随后 N 行&#xff0c;每行给…

单片机原理及应用:中断系统结构与控制寄存器

大家好啊&#xff0c;这几天因为考试断更了一段时间&#xff0c;现在放假了也可以恢复正常的更新速度了。今天我们来认识一下单片机的中断系统&#xff0c;这里可以说是我们学习单片机以来第一个核心功能&#xff0c;我们会分几期内容来深入了解中断系统的作用原理和应用方式。…

vue+springboot+mybatis-plus实现乡村公共文化服务系统

项目前端&#xff1a;https://gitee.com/anxin-personal-project/rural-public-cultural-services-front 项目后端&#xff1a;https://gitee.com/anxin-personal-project/rural-public-cultural-services-behind 1.系统简介 乡村公共服务文化提供给管理员、商家、村民。管理…

36-javascript输出方式,弹框:普通,confirm弹框,prompt弹框,控制台输出:普通,warm,error

1.页面打印 <body><p>你真是一个小机灵鬼</p><script>// 页面打印document.write("打印内容");</script> </body> 2.覆盖文档 <body><p>你真是一个小机灵鬼</p><script>// 覆盖文档window.onload f…

用Java编写图书网站信息采集程序教程

目录 一、准备工作 二、分析目标网站结构 三、选择信息采集方式 四、安装Jsoup库 五、编写信息采集程序 六、注意事项 总结&#xff1a; 编写图书网站信息采集程序需要掌握HTML、CSS、JavaScript、Java等前端和后端技术。下面是一个简单的教程&#xff0c;介绍如何使用…

1880_安装QEMU_for_ARC

Grey 全部学习内容汇总&#xff1a; https://github.com/GreyZhang/g_ARC 主标题 想学习一点ARC相关的知识&#xff0c;但是手里没有开发板。看了下&#xff0c;使用QEMU似乎是一个很好的选择&#xff0c;正好也有这么一个分支。在此&#xff0c;记录一下环境搭建的过程。 …

一文快速学会Docker软件部署

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;首期文章 &#x1f4da;订阅专栏&#xff1a;Docker 希望文章对你们有所帮助 做项目的时候&#xff0c;感觉很多地方的配置都特别…

扫码能看图片吗?图片怎么弄成二维码?

在外出游玩或者参加展览时&#xff0c;经常会看到很多的物品或者展物都会有一个对应的二维码&#xff0c;通过扫码就可以查看详情&#xff0c;其中很多的内容为了美观性都会单独将内容设计成图片存入二维码中&#xff0c;那么图片制作二维码怎么制作呢&#xff1f; 想要快速的…

数模学习day10-聚类模型

说明&#xff0c;本文部分图片和内容源于数学建模交流公众号 目录 K-means聚类算法 K-means聚类的算法流程&#xff1a; 图解 算法流程图 评价 K-means算法 基本原则 算法过程 Spss软件操作 K-means算法的疑惑 系统&#xff08;层次&#xff09;聚类 算法流程 Sp…

安卓逆向某脚本-autojs逆向

引言 上次讲到,为了静态分析,逆向了所有加密字符串。来看下今天我们看下他的流程。 分析app 启动之后会出现一个更新按钮,如图:我们先看下一般autojs 项目是怎么打包的,打包的时候可以选择加密类型,选择dex 类型,然后就是把js 文件变成dex 。 我们先看下一般autojs 项目是…

【python】TCP测速程序

一、服务端 下面是一个简单的 Python 服务端程序的示例&#xff0c;使用标准库中的 socket 模块来建立一个 TCP 服务器。该服务器接收客户端的连接请求&#xff0c;客户端发送一定大小的数据流以测试 TCP 带宽。 实际场景中带宽测试可能需要更复杂的逻辑来确保测试的准确性。 …

万能字符单词拼写 - 华为OD统一考试

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C++ 题目描述 有一个字符串数组 words 和一个字符串 chars。假如可以用 chars 中的字母拼写出 words 中的某个"单词"(字符串),那么我们就认为你掌握了这个单词。 words 的字符仅由 a-z 英文小写宁母组成,…

浅析内存一致性:内存屏障

文章目录 概述内存乱序访问Store Buffer和Invalidate QueueStore BufferStore ForwardingStore Buffer与内存屏障 Invalidate QueueInvalidate Queue与内存屏障 内存屏障分类编译器屏障CPU内存屏障 相关参考 概述 内存屏障&#xff0c;是一类同步屏障指令&#xff0c;是CPU或编…

分布式锁3: zk实现分布式锁2 使用临时节点(需要自旋)

一 使用临时节点实现分布式锁 1.1 代码截图 1.2 代码如下 由于zookeeper获取链接是一个耗时过程&#xff0c;这里可以在项目启动时&#xff0c;初始化链接&#xff0c;并且只初始化一次。借助于spring特性&#xff0c;代码实现如下&#xff1a; package com.atguigu.distri…

Spring MVC MVC介绍和入门案例

1.SpringMVC概述 1.1.MVC介绍 MVC是一种设计模式&#xff0c;将软件按照模型、视图、控制器来划分&#xff1a; M&#xff1a;Model&#xff0c;模型层&#xff0c;指工程中的JavaBean&#xff0c;作用是处理数据 JavaBean分为两类&#xff1a; 一类称为数据承载Bean&#xf…

逆向数据宽度与符号

正数与负数的 刚好是半 所以 0 表示正数 1表示负数 有符号与无符号是程序员定的 并不是开头是1就表示负数 0表示正数 得看有无符号 双字 32bit 4字节

【UE Niagara学习笔记】04 - 火焰喷射时的黑烟效果

目录 效果 步骤 一、创建烟雾材质 二、添加新的发射器 三、设置新发射器 3.1 删除Color模块 3.2 减少生成的粒子数量 3.3 设置粒子初始颜色 3.4 设置烟雾的位置偏移 3.5 设置烟雾淡出 在上一篇博客&#xff08;【UE Niagara学习笔记】03 - 火焰喷射效果&#xf…

机器学习(四) -- 模型评估(4)

系列文章目录 机器学习&#xff08;一&#xff09; -- 概述 机器学习&#xff08;二&#xff09; -- 数据预处理&#xff08;1-3&#xff09; 机器学习&#xff08;三&#xff09; -- 特征工程&#xff08;1-2&#xff09; 机器学习&#xff08;四&#xff09; -- 模型评估…