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
這樣就省下了很大空間。
看看測試例子
package com;import java.util.BitSet;public class MainTestThree {/** * @param args */public static void main(String[] args) {BitSet bm=new BitSet();System.out.println(bm.isEmpty()+"--"+bm.size());bm.set(0);System.out.println(bm.isEmpty()+"--"+bm.size());bm.set(1);System.out.println(bm.isEmpty()+"--"+bm.size());System.out.println(bm.get(65));System.out.println(bm.isEmpty()+"--"+bm.size());bm.set(65);System.out.println(bm.isEmpty()+"--"+bm.size());}}
輸出:
true--64
false--64
false--64
false
false--64
false--128
說明預設的建構函式聲明一個64位的BitSet,值都是false。
如果你要用的位超過了預設size,它會再申請64位,而不是報錯。
package com;import java.util.BitSet;public class MianTestFour {/** * @param args */public static void main(String[] args) {BitSet bm1=new BitSet(7);System.out.println(bm1.isEmpty()+"--"+bm1.size());BitSet bm2=new BitSet(63);System.out.println(bm2.isEmpty()+"--"+bm2.size());BitSet bm3=new BitSet(65);System.out.println(bm3.isEmpty()+"--"+bm3.size());BitSet bm4=new BitSet(111);System.out.println(bm4.isEmpty()+"--"+bm4.size());}}
輸出:
true--64
true--64
true--128
true--128
說明你申請的位都是以64為倍數的,就是說你申請不超過一個64的就按64算,超過一個不超過
2個的就按128算。
package com;import java.util.BitSet;public class MainTestFive {/** * @param args */public static void main(String[] args) {int[] shu={2,42,5,6,6,18,33,15,25,31,28,37};BitSet bm1=new BitSet(MainTestFive.getMaxValue(shu));System.out.println("bm1.size()--"+bm1.size());MainTestFive.putValueIntoBitSet(shu, bm1);printBitSet(bm1);}//初始全部為false,這個你可以不用,因為預設都是falsepublic static void initBitSet(BitSet bs){for(int i=0;i<bs.size();i++){bs.set(i, false);}}//列印public static void printBitSet(BitSet bs){StringBuffer buf=new StringBuffer();buf.append("[\n");for(int i=0;i<bs.size();i++){if(i<bs.size()-1){buf.append(MainTestFive.getBitTo10(bs.get(i))+",");}else{buf.append(MainTestFive.getBitTo10(bs.get(i)));}if((i+1)%8==0&&i!=0){buf.append("\n");}}buf.append("]");System.out.println(buf.toString());}//找出資料集合最大值public static int getMaxValue(int[] zu){int temp=0;temp=zu[0];for(int i=0;i<zu.length;i++){if(temp<zu[i]){temp=zu[i];}}System.out.println("maxvalue:"+temp);return temp;}//放值public static void putValueIntoBitSet(int[] shu,BitSet bs){for(int i=0;i<shu.length;i++){bs.set(shu[i], true);}}//true,false換成1,0為了好看public static String getBitTo10(boolean flag){String a="";if(flag==true){return "1";}else{return "0";}}}
輸出:
maxvalue:42
bm1.size()--64
[
0,0,1,0,0,1,1,0,
0,0,0,0,0,0,0,1,
0,0,1,0,0,0,0,0,
0,1,0,0,1,0,0,1,
0,1,0,0,0,1,0,0,
0,0,1,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0
]
這樣便完成了存值和取值。
注意它會對重複的數字過濾,就是說,一個數字出現過超過2次的它都記成1.
出現的次數這個資訊就丟了。