Java实现位图功能

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

posted @ 2020-08-11 18:07  zslm___  阅读(1376)  评论(0编辑  收藏  举报