位图的原理和简单实现

位图(bitmap)的原理是用一个位来表示一个数字(准确说是用数组下标和一个位来表示)。

java中一个int类型占4Byte,32字节。如果我们使用位图来存储数据。那么一个int类型就可以存储32个数据。

   //假设我们要存储20亿整数
    private static final int N = 2000000000;
    //如果按照普通数组方式存储 我们需要开辟一个new int[N]的空间
    //但是使用位图 我们使用的空间是原来的 1/32
    private int[] a = new int[N / 32 + 1];

    public int[] getA() {
        return a;
    }

    /**
     * row = n / 32 求整数n在数组a中的下标 如 n = 7 那么它在数组下标为0的位置
     * n=32(32/32=1) 那么它在数组下标为1的位置
     * a[row] |= 1 << (n & 0x1F) 这个语句是求n在对应下标的具体位置
     * n & 0x1F 表示将n和31求与  如n = 7 那么7 & 0x1F = 7 表示在0中的位置为7
     * 如n = 32 那么32 & 0x1F = 0 表示在0中的位置为0
     * 1 << (n & 0x1F) n % 32
     *
     * @param n
     */
    public void addValue(int n) {
        int row = n >> 5;
        //相当于 n % 32 求十进制数在数组a[i]中的下标
        a[row] |= 1 << (n & 0x1F);
    }

    // 判断所在的bit为是否为1
    public boolean exists(int n) {
        int row = n >> 5;
        return (a[row] & (1 << (n & 0x1F))) == 1;
    }

  文件去重测试

 /**
     * 随机输入200万整数
     * 存到value.txt中
     * @throws IOException
     */
    public  void randomValues() throws IOException {
        FileWriter writer = null;
        File file = new File("value.txt");
        if (!file.exists()) {
            file.createNewFile();
        }
        writer = new FileWriter(file);
        for (int i = 0; i < 2000000; i++) {
            int a = (int) (Math.random() * 100000000);
            writer.write(a + System.getProperty("line.separator"));
        }
        writer.flush();
    }

    /**
     * 去重读到 value1.txt中
     * @throws IOException
     */
    public void reValues() throws IOException {
        File file = new File("value.txt");
        File file1 = new File("value1.txt");
        FileWriter writer = new FileWriter(file1);
        if (!file1.exists()) {
            file1.createNewFile();
        }
        BufferedReader reader = new BufferedReader(new FileReader(file));
        String string = null;
        int count = 0;
        while ((string = reader.readLine()) != null) {
            int temp = Integer.parseInt(string);
            if (!exists(temp)) {
                count++;
                this.addValue(temp);
                writer.write(temp + System.getProperty("line.separator"));
            }
        }
        writer.flush();
        System.out.println(count);
    }

  

posted @ 2019-11-11 17:06  小小小小的我  阅读(1100)  评论(0编辑  收藏  举报