zoukankan      html  css  js  c++  java
  • BitSet 是个好东西

    顾名思义,就是位集合(bit set),是从JDK 1.0就出现的东西,后面的版本又慢慢强化。

    我们说学习一样东西,最好是场景驱动 - 要考虑它的使用场景,这样才有意义。

    那么,BitSet的应用场景是什么?

    我个人的体会是,用于统计,统计整数相关的东西。但这么说未免太空泛了,我们先来看一下它的用法吧。

    直接上例子:

    @Test
    public void test(){
        BitSet set = new BitSet(10); //10 bits set
    
        //set() 设为true
        set.set(0);
        set.set(1);
        set.set(5);
        System.out.println(set); // 应该是列出值为true的那些位的坐标!
    
        // 8 bit >> 1 byte,  就是说截取8位,转成byte。 就是0010 0011 >>
        System.out.println(Arrays.toString(set.toByteArray()));
        // 64 bit >> 1 long
        System.out.println(Arrays.toString(set.toLongArray()));
    }
     

    方法体内:

    第一部分是创建对象,该构造方法接收一个int来指明位集合的长度 -- [0,0,0,0,  0,0,0,0,  0,0]。注意,此时所有位的值都是false - 这里的false不是Java中的概念,而是对应bit的0 -- true对应1。

    第二部分是设置位值,BitSet#set(int n) 方法是将第n位的值设为true(1) --  [1,1,0,0,  0,1,0,0,  0,0]!直接输出的话,就是位值为true的索引:{0, 1, 5}!

    第三部分,是将所有位转成byte数组、long数组,并输出对应的数组内容。转成byte[],其实就是每8位切分一下;转成long[]就是每64位切分一下!那么[1,1,0,0,  0,1,0,0,  0,0]就是[(1,1,0,0,  0,1,0,0,)  0,0],也就是[35]!注意计算方式。

    再来一个逆向的例子:

    @Test
    public void test1(){
        // 和test()中的set.toByteArray()刚好相反,这里是1 byte >> 8 bits! 需要确认90对应的低8bit 还是高8bit。
        BitSet bitSet = BitSet.valueOf(new byte[]{90, 92, 95, 97});
        System.out.println(bitSet); //{1, 3, 4, 6, 10, 11, 12, 14, 16, 17, 18, 19, 20, 22, 24, 29, 30}
    
        //截取下上面的输出即可知道90对应的是低位还是高位
        BitSet bs = new BitSet(8);//
        bs.set(1);
        bs.set(3);
        bs.set(4);
        bs.set(6);
        System.out.println(Arrays.toString(bs.toByteArray()));//90 - 事实证明是小端?
    }

    这里就是将byte[]或long[]中的每个值拆成8bit或者64bit的形式,填入相应的位置(8*index ~ 8*(index+1),或64*index ~ 64*(index+1))。

    然后,具体的计算就跟2进制转8进制或16进制一样,每三位一算,或每四位一算!只不过这里是每8位或每64位一算!

    那回到前面的主题,这有什么应用场景?

    举个例子,比如你要生成随机数,整数,不多,就 0~1亿范围吧,生成的数量不定,现在让你列出所有生成的数值,甚至按照大小排序,你怎么做?

    难道是搞一个HashSet<Integer>?哪怕是按照int类型的长度,最大也会4B*100000000 ≈ 381 MB,性能绝对是个问题,还得排序,估计得到地老天荒。

    用BitSet就方便多了,怎么用呢?

    直接搞一个 new BitSet(100000000),内存不过是 100000000/8 B ≈ 12 MB!

    然后,每得到一个随机数,就将相应的位设为true即可,bs.set(num)!

    最后,直接输出所有位值为true的索引即可,无论从小到大,还是反过来,都很简单!

    怎么样,有没有一种惊喜的感觉,哈哈,起码我觉得很惊喜。

    噢对了,这货C++中也有。

    至于BitSet其他的操作,留给各位自行探索吧。

  • 相关阅读:
    node相关--socket.io
    node相关--WebSocket
    node工具--express
    node工具--connect
    HTTP基础01--web与互联网基础
    nodeAPI--HTTP
    nodeAPI--TCP
    js:语言精髓笔记13--语言技巧
    js:语言精髓笔记12--动态语言特性(2)
    js:语言精髓笔记11--动态语言特性(1)
  • 原文地址:https://www.cnblogs.com/larryzeal/p/7710389.html
Copyright © 2011-2022 走看看