大数据处理算法之一:BitMap
如有错误,欢迎指正
1.(1)通过存储2表示是十进制的数进制位
如图:
(2)可以快速排序/查找:bitmap.set(11),会直接在11的位上置为1,查询的时候直接查询这个位置是否是1,可以快速查找。
使用场景:
a.大量的黑名单号码需要存储,并且频繁访问,每次发送短信,这样就可以把黑名单号码存储到bitmap里面,通过boolean bitmap.get(11)方法,判断是否存在
b.现在有五十亿个int类型的正整数,要从中找出重复的数并返回?
思路:循环数据,把数据存到bitmap中,每次都判断是否存在在bitmap中,使用set(重复的数据只会保存一个)装bitmap中存在的数据,返回set即可
(3)
1G = 1024M
1M = 1024KB
1KB = 1024B(字节)
1M =(1024 * 1024)字节Byte
1字节 = 8个二进制位(bit)
注意:有些时候在实际中,为了计算方便,计算机行业绝大多数的存储硬件设备生产制造商将1024进制改成了1000进制
2.使用过的bitmap和bitset
(1)com.sleepycat.je.utilint 包下面有一个BitMap,添加的参数是long类型的,里面也用到java.util包下面的BitSet(添加的参数类型是int的)。
依赖如下:
<dependency>
<groupId>com.sleepycat</groupId>
<artifactId>je</artifactId>
<version>5.0.73</version>
</dependency>
(2)BitMap底层也是通过BitSet, 存进来的数是与65535L做逻辑与运算,(65535L:二进制中表示是16个1,转换成10进制正好是65535。unsingn int 一个整数是2个字节,有2*8个字符)
(3)如下是com.sleepycat包下的bitmap类,可以看出这个类也是使用了java.util包下的bitset
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
package com.sleepycat.je.utilint;
import com.sleepycat.je.EnvironmentFailureException;
import java.util.BitSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class BitMap {
private static final int SEGMENT_SIZE = 16;
private static final int SEGMENT_MASK = 65535;
private Map<Long, BitSet> bitSegments = new HashMap();
public BitMap() {
}
public void set(long index) throws IndexOutOfBoundsException {
if(index < 0L) {
throw new IndexOutOfBoundsException(index + " is negative.");
} else {
BitSet bitset = this.getBitSet(index, true);
if(bitset == null) {
throw EnvironmentFailureException.unexpectedState(index + " is out of bounds");
} else {
int useIndex = this.getIntIndex(index);
bitset.set(useIndex);
}
}
}
public boolean get(long index) throws IndexOutOfBoundsException {
if(index < 0L) {
throw new IndexOutOfBoundsException(index + " is negative.");
} else {
BitSet bitset = this.getBitSet(index, false);
if(bitset == null) {
return false;
} else {
int useIndex = this.getIntIndex(index);
return bitset.get(useIndex);
}
}
}
private BitSet getBitSet(long index, boolean allowCreate) {
Long segmentId = Long.valueOf(index >> 16);
BitSet bitset = (BitSet)this.bitSegments.get(segmentId);
if(allowCreate && bitset == null) {
bitset = new BitSet();
this.bitSegments.put(segmentId, bitset);
}
return bitset;
}
private int getIntIndex(long index) {
return (int)(index & 65535L);
}
int getNumSegments() {
return this.bitSegments.size();
}
int cardinality() {
int count = 0;
BitSet b;
for(Iterator iter = this.bitSegments.values().iterator(); iter.hasNext(); count += b.cardinality()) {
b = (BitSet)iter.next();
}
return count;
}
}
补充:左移<<变大,左移多少位,就在后面加几个0;右移>>变小,右移多少位,就在末尾砍掉几个数。