1.
public class Bitmap { /** * bitmap實際存儲處 */ private byte[] buf; /** * 偏移基准位 */ private int base; /** * .ctor * * @param capacity bitmap總長度 * @param base 偏移基准位. 假設 userId一般是從10_000開始,那么 建立一個bitMap為 2_000的長度時 capacity為2_000,base為就是 10_000, */ public Bitmap(int capacity, int base) { this.buf = new byte[(int) (capacity / 8) + 1]; this.base = base; } /** * .ctor * * @param capacity bitmap總長度 */ public Bitmap(int capacity) { this(capacity, 0); } /** * 根據偏移位獲取狀態 * 將1左移position后,那個位置自然就是1,然后和以前的數據做&,判斷是否為0即可 * @param offset 偏移位 * @return 返回值為 1或者0 */ public byte getbit(int offset) { int actualOffset = getActualOffset(offset); int index = getIndex(actualOffset); byte b = buf[index]; return (byte) ((b & (1 << getPosition(actualOffset))) != 0 ? 1 : 0); } /** * 設置偏移位所在狀態為1 * 將1左移position后,那個位置自然就是1,然后和以前的數據做 或| 操作.這樣,那個位置就替換成1了 * @param offset 偏移位 */ public void setbit(int offset) { int actualNum = getActualOffset(offset); int index = getIndex(actualNum); byte b = buf[index]; buf[index] = (byte) (b | (1 << getPosition(actualNum))); } /** * 設置偏移位所在狀態為0 * 對1進行左移,然后取反,最后與buf[index]作 與& 操作。 * @param offset 偏移位 */ public void clear(int offset) { int actualNum = getActualOffset(offset); int index = getIndex(actualNum); byte b = buf[index]; buf[index] = (byte) (b & ~(1 << getPosition(actualNum))); } /** * 獲取當前偏移offset在數組中的索引 * Offset/8得到byte[]的index */ private int getIndex(int actualOffset) { // 相當於 Offset / 8 (因為8 是2^n次方,所以可以這樣取整) return (actualOffset) >> 3; } /** * 獲取當前偏移offset在字節里的位數 * Offset % 8得到byte 的 pos */ private int getPosition(int actualOffset) { // 相當於 Offset % 8 (因為8 是2^n次方,所以可以這樣取模) return (actualOffset) & 0x07; } private int getActualOffset(int offset) { return offset - base; } }
2.
public static void main(String[] args) { // 假設user_id的基准是 50W(用戶id為 500001,500002...) // 當前系統里有1W個用戶,則設計bitmap如下: int base = 500_000; Bitmap bitmap = new Bitmap(10000, base); // 對 500009 設置 1 bitmap.setbit(500009); System.out.println(bitmap.getbit(500009)); System.out.println(bitmap.getbit(500008)); System.out.println(bitmap.getbit(500010)); // 對 500009 設置 0 bitmap.clear(500009); // 對 500010 設置 1 bitmap.setbit(500010); System.out.println(bitmap.getbit(500009)); System.out.println(bitmap.getbit(500008)); System.out.println(bitmap.getbit(500010)); }
3. 結果
1
0
0
0
0
1