淘先锋技术网

首页 1 2 3 4 5 6 7

位图概念、用法及实现

1 概念

位图(BitMap)可以用极少的空间保存很大的数值
通过一个bit数组来存储特定数据的一种数据结构,每一个bit位都能独立包含信息,bit是数据的最小存储单元,因此能大量节省空间

我们都知道在Java中int类型是占四个Byte,一个Byte有8bit
1 0 0 0 0 0 0 0 0 【8bit,一个字节,此时1在第8位,可以表示7这个数】
下面我们使用的是long类型,因此可以表示0~63(共64位数)

2 实现

BitMap:

public static class BitMap{
    private long[] bits;
    public BitMap(int max){
        //(max + 64) >> 6 等同于 (max + 64) / 64
        bits = new long[(max + 64) >> 6];
    }
    public void add(int num){
        //num >> 6 等同于 num / 64 【可以确定我们要添加的整数】
        // num % 64 等同于 num & 63
        bits[num >> 6] |= (1L << (num & 63));//利用|运算,将对应位置置为1
    }
    public void delete(int num){
        bits[num >> 6] &= ~(1L << (num & 63));
    }
    public boolean contains(int num){
        return (bits[num >> 6] & (1L << (num & 63))) != 0;//与对应位置相与,判断结果是否为0
    }
}

全代码及测试代码:
BitMapTest:

测试代码与hash表进行比较,观察所存数字

public class BitMapTest {

    public static class BitMap{
        private long[] bits;
        public BitMap(int max){
            //(max + 64) >> 6 等同于 (max + 64) / 64
            bits = new long[(max + 64) >> 6];
        }
        public void add(int num){
            //num >> 6 等同于 num / 64 【可以确定我们要添加的整数】
            // num % 64 等同于 num & 63
            bits[num >> 6] |= (1L << (num & 63));//利用|运算,将对应位置置为1
        }
        public void delete(int num){
            bits[num >> 6] &= ~(1L << (num & 63));
        }
        public boolean contains(int num){
            return (bits[num >> 6] & (1L << (num & 63))) != 0;//与对应位置相与,判断结果是否为0
        }
    }

    public static void main(String[] args) {
        System.out.println("测试开始-----");
        int max = 10000;
        BitMap bitMap = new BitMap(max);
        HashSet<Integer> set = new HashSet<>();
        int testTime = 1000000;
        for (int i = 0; i < testTime; i++) {
            int num = (int)(Math.random() * (max + 1));
            double decide = Math.random();
            if(decide < 0.333){
                bitMap.add(num);
                set.add(num);
            } else if(decide < 0.666){
                bitMap.delete(num);
                set.remove(num);
            } else {
                if(bitMap.contains(num) != set.contains(num)){
                    System.out.println("Oops .....");
                    break;
                }
            }
        }
        for (int num = 0; num <= max; num++) {
            if(bitMap.contains(num) != set.contains(num)){
                System.out.println("Oops....");
            }
        }
        System.out.println("测试结束----");
    }
}