Java.util.BitSet可以按位存儲(chǔ)。 計(jì)算機(jī)中一個(gè)字節(jié)(byte)占8位(bit)伏恐,我們java中數(shù)據(jù)至少按字節(jié)存儲(chǔ)的, 比如一個(gè)int占4個(gè)字節(jié)。 如果遇到大的數(shù)據(jù)量璧针,這樣必然會(huì)需要很大存儲(chǔ)空間和內(nèi)存。 如何減少數(shù)據(jù)占用存儲(chǔ)空間和內(nèi)存可以用算法解決渊啰。 java.util.BitSet就提供了這樣的算法探橱。
比如有一堆數(shù)字,需要存儲(chǔ)绘证,source=[3,5,6,9] 用int就需要4*4個(gè)字節(jié)隧膏。 。 如果用java.util.BitSet嚷那,則會(huì)少很多胞枕,其原理是:
先找出數(shù)據(jù)中最大值maxvalue=9
聲明一個(gè)BitSet bs,它的size是maxvalue+1=10
遍歷數(shù)據(jù)source,bs[source[i]]設(shè)置成true.
最后的值是:
[0,0,0,1,0,1,1,0,0,1]3569
這樣一個(gè)本來(lái)要int型需要占4字節(jié)共32位的數(shù)字現(xiàn)在只用了1位魏宽! 比例32:1
這樣就省下了很大空間腐泻。
BitSet是位操作的對(duì)象,值只有0或1即false和true湖员,最常用的地方是用戶贫悄、系統(tǒng)開(kāi)關(guān),原理是內(nèi)部維護(hù)了一個(gè)long數(shù)組娘摔,初始只有一個(gè)long窄坦,所以BitSet最小的size是64,當(dāng)隨著開(kāi)關(guān)越來(lái)越多,會(huì)動(dòng)態(tài)擴(kuò)充鸭津,最終內(nèi)部是由N個(gè)long來(lái)存儲(chǔ)彤侍,這些對(duì)操作都是透明的。
final BitSet bs = new BitSet();
默認(rèn)的構(gòu)造函數(shù)聲明一個(gè)64位的BitSet逆趋,值都是false盏阶。 如果你要用的位超過(guò)了默認(rèn)size,它會(huì)再申請(qǐng)64位,而不是報(bào)錯(cuò)
public void set(int pos): 位置pos的字位設(shè)置為true闻书。
public void set(int bitIndex, boolean value) 將指定索引處的位設(shè)置為指定的值名斟。
public void clear(int pos): 位置pos的字位設(shè)置為false。
public void clear() : 將此 BitSet 中的所有位設(shè)置為 false魄眉。
public int cardinality() 返回此 BitSet 中設(shè)置為 true 的位數(shù)砰盐。
public boolean get(int pos): 返回位置是pos的字位值。
public void and(BitSet other): other同該字位集進(jìn)行與操作坑律,結(jié)果作為該字位集的新值岩梳。
public void or(BitSet other): other同該字位集進(jìn)行或操作,結(jié)果作為該字位集的新值晃择。
public void xor(BitSet other): other同該字位集進(jìn)行異或操作冀值,結(jié)果作為該字位集的新值。
public void andNot(BitSet set) 清除此 BitSet 中所有的位,set - 用來(lái)屏蔽此 BitSet 的 BitSet
public int size(): 返回此 BitSet 表示位值時(shí)實(shí)際使用空間的位數(shù)宫屠。
public int length() 返回此 BitSet 的“邏輯大小”:BitSet 中最高設(shè)置位的索引加 1列疗。
bites.toByteArray();
bites.toLongArray();
BitSet.valueOf(byte[]);
//一個(gè)字符串中用了哪些字符@TestpublicvoidcharCalc(){finalString wordstr ="hello, world 你好嗎";finalBitSet bs =newBitSet();for(charc : wordstr.toCharArray()){? ? ? ? ? ? bs.set(c);//System.out.println("-------------");}? ? ? ? System.out.println(bs.size());? ? ? ? System.out.println(bs.length());for(inti=0; i maxnum)break;? ? ? ? ? ? ? ? bs.set(x);? ? ? ? ? ? ? ? j++;? ? ? ? ? ? }? ? ? ? }for(inti=2;i<=maxnum;i++){if(!bs.get(i))? System.out.println(i);? ? ? ? }? ? }
//現(xiàn)在有1千萬(wàn)個(gè)隨機(jī)數(shù),隨機(jī)數(shù)的范圍在1到1億之間±缩澹現(xiàn)在要求寫出一種算法作彤,將1到1億之間沒(méi)有在隨機(jī)數(shù)中的數(shù)求出來(lái)@Testpublicvoidfindrandom(){
System.out.println("開(kāi)始生成隨機(jī)數(shù) "+newDate());finalint[] numbers =newint[10000000];for(inti=0;i
numbers[i] = RandomUtils.nextInt(1,100000001);
}
System.out.println("生成隨機(jī)數(shù)完畢 "+newDate());////////////////////////finalBitSet bs =newBitSet(numbers.length);for(intn : numbers){
bs.set(n);
}
System.out.println("設(shè)置位圖完畢 "+newDate());for(inti=1;i<100000001;i++){if(!bs.get(i))? System.out.println(i);//沒(méi)有在隨機(jī)數(shù)中//if(bs.get(i)) System.out.println(i);? //在隨機(jī)數(shù)中}
System.out.println("打印完畢 "+newDate());
}