BitMap源码的一些解读

package com.example.demo.bitMap;

public class BitMap {

    private int length;

    private static int[] bitsMap;
    //0X 表示16进制
    //0x00000001 : 二进制 0000 0000 0000 0000 0000 0000 0000 0001  从右向左数,从0开始,index : 0的比特位是 1
    //0x00000002 : 二进制 0000 0000 0000 0000 0000 0000 0000 0010  从右向左数,从0开始,index : 1的比特位是 1
    //0x00000004 : 二进制 0000 0000 0000 0000 0000 0000 0000 0100  从右向左数,从0开始,index : 2的比特位是 1
    //0x00000008 : 二进制 0000 0000 0000 0000 0000 0000 0000 1000  从右向左数,从0开始,index : 3的比特位是 1
    //0x00000010 : 二进制 0000 0000 0000 0000 0000 0000 0001 0000  从右向左数,从0开始,index : 4的比特位是 1
    //0x00000020 : 二进制 0000 0000 0000 0000 0000 0000 0010 0000  从右向左数,从0开始,index : 5的比特位是 1
    //......
    //0x00800000 : 二进制 0000 0000 1000 0000 0000 0000 0000 0000  从右向左数,从0开始,index : 23的比特位是 1
    //0x01000000 : 二进制 0000 0001 0000 0000 0000 0000 0000 0000  从右向左数,从0开始,index : 24的比特位是 1
    //0x02000000 : 二进制 0000 0010 0000 0000 0000 0000 0000 0000  从右向左数,从0开始,index : 25的比特位是 1
    //0x04000000 : 二进制 0000 0100 0000 0000 0000 0000 0000 0000  从右向左数,从0开始,index : 26的比特位是 1
    //0x08000000 : 二进制 0000 1000 0000 0000 0000 0000 0000 0000  从右向左数,从0开始,index : 27的比特位是 1
    //0x10000000 : 二进制 0001 0000 0000 0000 0000 0000 0000 0000  从右向左数,从0开始,index : 28的比特位是 1
    //0x20000000 : 二进制 0010 0000 0000 0000 0000 0000 0000 0000  从右向左数,从0开始,index : 29的比特位是 1
    //0x40000000 : 二进制 0100 0000 0000 0000 0000 0000 0000 0000  从右向左数,从0开始,index : 30的比特位是 1
    //0x80000000 : 二进制 1000 0000 0000 0000 0000 0000 0000 0000  从右向左数,从0开始,index : 31的比特位是 1
    private static final int[] BIT_VALUE = {0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020,
            0x00000040, 0x00000080, 0x00000100, 0x00000200, 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000,
            0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000,
            0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000};

    public BitMap(int length){
        this.length = length;
//        int size = (int)length / 32(2^5) + (int)length % 32 == 0 ? 0 : 1;
//        int size = length >> 5 + (((length & 31) == 0)? 0 : 1);
        //根据length算出,bitsMap的长度
        bitsMap = new int[length >> 5 + (((length & 31) == 0)? 0 : 1)];
    }

    /**
     * 向bitsMap中存入数值 n
     * @param n
     */
    public void setN(int n){
        /*//判断 n 放入bitsMap数组中那个索引位置
        int index = n / 32(2^5);
        int index = n>>5;
        //判断 n 需要在 bitsMap[index]中 那个位置做标记 标记1
        int offset = n % 32;
        int offset = n & 31;
        int bit = bitsMap[index];
        BIT_VALUE[offset] : 表示 需要做索引的位置
        例: n=3
         int index = n>>5 =0
         int offset = n&31=3
         bit = bitsMap[index] =  bitsMap[0] = 0      二进制 0000 0000 0000 0000 0000 0000 0000 0000
         BIT_VALUE[offset] = BIT_VALUE[3] 0x00000008 二进制 0000 0000 0000 0000 0000 0000 0000 1000
         bit = bit | BIT_VALUE[offset]               二进制 0000 0000 0000 0000 0000 0000 0000 1000*/
        if (n < 0 || n > length) {
            throw new IllegalArgumentException("length value "+n+" is  illegal!");
        }
        bitsMap[n>>5] |= BIT_VALUE[n&31];
    }

    /**
     * 获取值N是否存在
     * @param n
     * @return 1:存在,0:不存在
     */
    public int isExist(int n){
        if (n < 0 || n > length) {
            throw new IllegalArgumentException("length value "+n+" is  illegal!");
        }
        // 例如: n=3 假设此时bitsMap中已经存了 n=3
        /* >>>表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0
        int index = n>>5 =0
        int offset = n&31=3
        int bits = bitsMap[index] = bitsMap[0]      二级制 0000 0000 0000 0000 0000 0000 0000 1000
        BIT_VALUE[offset] = BIT_VALUE[3] 0x00000008 二级制 0000 0000 0000 0000 0000 0000 0000 1000
        bits & BIT_VALUE[3]                         二级制 0000 0000 0000 0000 0000 0000 0000 1000 很重要
        (bits & BIT_VALUE[3]) >>> 3                 二级制 0000 0000 0000 0000 0000 0000 0000 0001*/
        int index = n>>5;
        int offset = n&31;
        System.out.println("n="+n+",index="+ index +",offset=" + offset +",bits="+Integer.toBinaryString(bitsMap[index]));
        return (bitsMap[index] & BIT_VALUE[offset]) >>> offset;
    }

    /**
     * 移除 n
     * @param n
     */
    public void clear(int n){
        if (n < 0 || n > length) {
            throw new IllegalArgumentException("length value "+n+" is  illegal!");
        }
        int index = n>>5;
        int offset = n&31;
        // 例如: n=3 假设此时bitsMap中已经存了 n=3
        // int offset = 3&31 = 3
        // 1              二进制 0000 0000 0000 0000 0000 0000 0000 0001
        // 1 左移后的结果
        // 1<<offset 1<<3 二进制 0000 0000 0000 0000 0000 0000 0000 1000
        // ~(1<<offset)   二进制 1111 1111 1111 1111 1111 1111 1111 0111
        //bitsMap[index]  二进制 0100 0000 0000 0000 0000 0000 0000 1000
        //~(1<<offset) & bitsMap[index] 结果:
        //                二进制 0100 0000 0000 0000 0000 0000 0000 0000
        bitsMap[index] &= ~(1 << offset);
    }


    public static void main(String[] args) {
        BitMap bitMap = new BitMap(300);
        bitMap.setN(30);
        bitMap.setN(3);
        //bitsMap[0] 中的数值:               二级制 0100 0000 0000 0000 0000 0000 0000 1000
        int exist = bitMap.isExist(3);
        // isExist的运算过程:
        //BIT_VALUE[3]                      二级制 0000 0000 0000 0000 0000 0000 0000 1000
        //bitsMap[0] & BIT_VALUE[3] 结果    二级制 0000 0000 0000 0000 0000 0000 0000 1000
        //bitsMap[0] & BIT_VALUE[3] >>> 3  二级制 0000 0000 0000 0000 0000 0000 0000 0001
        System.out.println("exist = " + exist);
        bitMap.clear(3);
        exist = bitMap.isExist(3);
        System.out.println("exist = " + exist);
        /*
        int a = 6;
        int b = 4;
        int c = a%b
        System.out.println(" 1 .....  a%b = " + c); // 1 .....  a%b = 2
            c = a&(b-1);
        System.out.println(" 2 .....  a&(b-1) = " + c); // 2 .....  a&(b-1) = 2

        // 1.位或运算 两个二进制对应位 同时为0时,则为0,否则为1;
        int a = 5; //0000 0101
        int b = 3; //0000 0011
        //a = a|b;   0000 0111
        a |= b; // 0000 0111 表示 10进制 7
        System.out.println("a = " + a);

        // 2.位与运算 两个二进制对应位 同时为1,则为1,否则为0
        int c = 5; //0000 0101
        int d = 3; //0000 0011
        //c = c&d;   0000 0001
        c &= d; // 0000 0001 表示 10进制 1
        System.out.println("c = " + c);

        // 3.位异或运算 两个二进制对应位 相同时为0,否则为1
        int e = 5; //0000 0101
        int f = 3; //0000 0011
        //e = e^f    0000 0110
        e ^= f; // 0000 0110 表示 10进制 6*/
    }


}

发布了4 篇原创文章 · 获赞 4 · 访问量 163

猜你喜欢

转载自blog.csdn.net/qq_42378705/article/details/104564166