Bitmap

 bitmap(位图)的数据结构

Java中的BitSet数据结构

01.Java中Bitset的使用
  Java中原生的bitmap的实现: BitSet
  BitSet 一个Bitset类创建一种特殊类型的数组来保存位值。BitSet中数组大小会随需要增加
    BitSet定义了两个构造方法:  BitSet()  BitSet(int size)
	BitSet的底层实现是使用long数组作为内部存储结构的
  变为Bitset
    cardinality( ) 返回此 BitSet 中设置为 true 的位数
	                    //就是BitSet中存放的有效位的个数,如果有重复运算会进行自动去重
    length()       返回此 BitSet 的"逻辑大小": BitSet 中最高设置位的索引加 1
    size( )        返回此 BitSet 表示位值时实际使用空间的位数
	                (即通过使用此BitSet表示位来分配给实际位数的内存)。128bit
   说明:  null 参数传递给 BitSet 中的任何方法都将导致 NullPointerException
基本操作
  Bitmap的基本操作有: set()  clear()  flip()
    初始化一个bitset,指定大小。
    清空bitset。
    反转某一指定位。
    设置某一指定位。
    获取某一位的状态。
    当前bitset的bit总位数。
	逻辑计算   and or andNot  xor
   排序: 按照顺序循环取出在BitSet存在的数,以此达到排序的目的
02. Bitset 源码:
   recalculateWordsInUse();  wordsInUse 是检查当前的long数组中,实际使用的long的个数
   checkInvariants();
  这两个函数,是对bitset的内部状态进行维护和检查的函

Roaringbitmap

container是RBM新创造的概念:
    ArrayContainer   BitmapContainer  RunContainer
具体的实现
  开源工具类 JavaEWAH 或者 RoaringBitmap
  开源工具实现-- EWAHCompressedBitmap(谷歌对Bitmap的实现)
    <dependency>
        <groupId>com.googlecode.javaewah</groupId>
        <artifactId>JavaEWAH</artifactId>
        <version>1.1.7</version>
    </dependency>
  开源工具实现
  	<dependency>
        <groupId>org.roaringbitmap</groupId>
        <artifactId>RoaringBitmap</artifactId>
        <version>0.8.1</version>
    </dependency>
1.Roaringbitmap  
  主要的操作 org.roaringbitmap.RoaringBitmap
      主要使用 add remove  bitmapOf()
              and or xor                   
   // 向r1中添加1、2、3、1000四个数字
      RoaringBitmap r1 = RoaringBitmap.bitmapOf(1, 2, 3, 1000);  
  2.  位图位于内存映射文件中,则可以改用 org.roaringbitmap.buffer 包	
ImmutableRoaringBitmap 和 MutableRoaringBitmap
  public class MutableRoaringBitmap extends ImmutableRoaringBitmap 
	          implements Cloneable, Serializable, Iterable<Integer>, Externalizable,
	          BitmapDataProvider, AppendableStorage<MappeableContainer> {}
从ByteBuffer创建ImmutableRoaringBitmap
	    ByteArrayOutputStream bos = new ByteArrayOutputStream()
		ByteBuffer bb = ByteBuffer.wrap(bos.toByteArray());
		ImmutableRoaringBitmap rrback1 = new ImmutableRoaringBitmap(bb);   
 3.,RoaringBitmap处理的是int类型的数据,但是在实际中我们使用的都是long类型的,可以使用Roaring64NavigableMap。
   Roaring64NavigableMap
  Roaring64NavigableMap也是使用拆分模式,将一个long类型数据,拆分为高32位与低32位,
   高32位代表索引,低32位存储到对应RoaringBitmap中,其内部是一个TreeMap类型的结构,会按照signed或者unsigned进行排序,key代表高32位,value代表对应的RoaringBitmap。 

应用场景

  01.给定含有40亿个不重复的位于[0, 4294967295]区间内的整数的集合,如何快速判定某个数是否在该集合内?
      正常Java int类型存储 2^32*4*8/8/2^10/2^10/2^10 = 16GB
     一个bit位代表一个整数是否存在,可以计算出所占用的大小就是  2^32*1/8/2^10/2^10 = 512M
  02.在3亿个整数中找出不重复的整数
  03. 已知某个文件内包含一些电话号码,每个号码为8位数字,统计不同号码的个数

参考:

 BitMap的原理和实现 https://www.cnblogs.com/myseries/p/10880641.html
 https://github.com/RoaringBitmap/RoaringBitmap 
 Python: 实现bitmap数据结构 https://my.oschina.net/goal/blog/200347
 RoaringBitmap精确去重 https://blog.csdn.net/lao000bei/article/details/105725579

分类:

技术点:

相关文章: