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