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*/
}
}
BitMap源码的一些解读
猜你喜欢
转载自blog.csdn.net/qq_42378705/article/details/104564166
今日推荐
周排行