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