Java Bitset类

java.util.BitSet可以按位存储。
计算机中一个字节(byte)占8位(bit),我们java中数据至少按字节存储的,
比如一个int占4个字节。
如果遇到大的数据量,这样必然会需要很大存储空间和内存。
如何减少数据占用存储空间和内存可以用算法解决。
java.util.BitSet就提供了这样的算法。
比如有一堆数字,需要存储,source=[3,5,6,9]
用int就需要4*4个字节。
java.util.BitSet可以存true/false。
如果用java.util.BitSet,则会少很多,其原理是:
1,先找出数据中最大值maxvalue=9
2,声明一个BitSet bs,它的size是maxvalue+1=10
3,遍历数据source,bs[source[i]]设置成true.
最后的值是:
(0为false;1为true)
bs [0,0,0,1,0,1,1,0,0,1]
3, 5,6, 9

这样一个本来要int型需要占4字节共32位的数字现在只用了1位!
比例32:1
这样就省下了很大空间。

以上转载自:https://blog.csdn.net/lushuaiyin/article/details/7546144

例子一: 利用Java中BitSet类计算2-200_0000之间素数个数和

 @Test
    public void bitSetTest() {


        int n = 200_0000;

        int count = 0;

        LocalDateTime beforeTime = LocalDateTime.now();

        BitSet bitSet = new BitSet(n + 1);



        int i;
        //第一步将所有数放入bitSet当中
        for (i = 2; i <= n; i++) {
            bitSet.set(i);
        }

        i = 2;
        while (i * i <= n) {
            if (bitSet.get(i)) {
                count++;
                int k = 2 * i;
                while (k <= n) {
                    bitSet.clear(k);
                    k += i;
                }
            }
            i++;
        }

        while (i <= n) {
            if (bitSet.get(i)) {
                count++;
            }
            i++;
        }

        LocalDateTime afterTime=LocalDateTime.now();
        System.out.println(beforeTime);
        System.out.println(afterTime);

        System.out.println("素数和计"+count);
    }

原作者链接:https://www.cnblogs.com/xujian2014/p/5491286.html

因在博客园没有账号遂在自己博客修正下员博主答案

例子二: 阿里的实习面试:
有1千万个随机数,随机数的范围在1到1亿之间。现在要求写出一种算法,将1到1亿之间没有在随机数中的数求出来?

    @Test

    public void randomListTest(){
        Random random=new Random();
        BitSet bitSet=new BitSet(100000000);
        int count=0;
        for(int i=0;i<10000000;i++)
        {
            int randomResult=random.nextInt(100000000);

            bitSet.set(randomResult);
        }

        for (int i = 0; i < 100000000; i++)
        {
            if(!bitSet.get(i))
            {
                count++;
            }
        }
        System.out.println("0~1亿不在上述随机数中有"+count);

    }

Java Bit学习:https://www.cnblogs.com/xupengzhang/p/7966755.html

例子三: 用户类别分为 活跃的 和 是会员的

如何找出是会员但是不活跃,为了让他继续为会员充值,我觉得应该是这个作用吧

先看结果展示吧:


全部用户ID:
[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ]
活跃用户ID:
[0 2 4 6 8 10 12 14 16 18 20 ]
会员用户ID:
[0 1 2 3 4 5 6 7 8 9 10 ]
不活跃用户ID:
[1 3 5 7 9 11 13 15 17 19 ]
不活跃会员ID:
[1 3 5 7 9 ]
可能不会再登录的用户ID:
[11 13 15 17 19 ]
    @Test
    public void randomBitSet(){
        Random random=new Random();
        //全部用户A
        BitSet a=new BitSet(20);
        //活跃用户B
        BitSet b=new BitSet(20);
        //会员用户C
        BitSet c=new BitSet(20);

        BitSet temp;


        //初始化全部用户
        for (int i = 0; i <=20; i++) {
            a.set(i);
        }
        //初始化活跃用户
        for (int i = 0; i <=20; i+=2) {
            b.set(i);
        }
        //初始化会员用户
        for (int i = 0; i <=10; i++) {
            c.set(i);
        }

        System.out.println("全部用户ID:");
        printBitSet(a,20);
        System.out.println("活跃用户ID:");
        printBitSet(b,20);
        System.out.println("会员用户ID:");
        printBitSet(c,20);

        //求出不活跃用户

        temp = new BitSet();
        temp.or(a);
        temp.xor(b);
        System.out.println("不活跃用户ID:");
        printBitSet(temp,20);



        temp = new BitSet();
        temp.or(b);
        //temp是活跃的会员ID
        temp.and(c);
        //活跃会员和会员进行异或后就是不活跃的
        temp.xor(c);
        System.out.println("不活跃会员ID:");
        printBitSet(temp,20);



        temp = new BitSet();
        temp.or(b);
        temp.or(c);
        temp.xor(a);
        System.out.println("可能不会再登录的用户ID:");
        printBitSet(temp,20);

//
//        temp = new BitSet();
//        temp.or(a);
//        temp.xor(b);
//        System.out.println("不活跃用户ID:");
//        printBitSet(temp,20);


    }


    private void printBitSet(BitSet bitSet,int length){
        System.out.print("[");
        for (int i = 0; i <=length; i++) {
            if (bitSet.get(i)){
                System.out.print(""+i+" ");
            }
        }
        System.out.print("]\n");
    }

我的位运算学习笔记: https://blog.csdn.net/boom_man/article/details/78030342

猜你喜欢

转载自blog.csdn.net/boom_man/article/details/80255980
今日推荐