posts - 110, comments - 101, trackbacks - 0, articles - 7
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          BitSet類 使用詳解 節省內存

          Posted on 2013-06-14 11:24 云云 閱讀(5061) 評論(0)  編輯  收藏

          (1)BitSet類
          大小可動態改變, 取值為true或false的位集合。用于表示一組布爾標志。

          此類實現了一個按需增長的位向量。位 set 的每個組件都有一個 boolean 值。用非負的整數將 BitSet 的位編入索引。可以對每個編入索引的位進行測試、設置或者清除。通過邏輯與、邏輯或和邏輯異或操作,可以使用一個 BitSet 修改另一個 BitSet 的內容。

          默認情況下,set 中所有位的初始值都是 false。

          每個位 set 都有一個當前大小,也就是該位 set 當前所用空間的位數。注意,這個大小與位 set 的實現有關,所以它可能隨實現的不同而更改。位 set 的長度與位 set 的邏輯長度有關,并且是與實現無關而定義的。

          除非另行說明,否則將 null 參數傳遞給 BitSet 中的任何方法都將導致 NullPointerException。 在沒有外部同步的情況下,多個線程操作一個 BitSet 是不安全的。

          (2) 構造函數: BitSet() or BitSet(int nbits)

          (3) 一些方法
          public void set(int pos): 位置pos的字位設置為true。
          public void set(int bitIndex, boolean value) 將指定索引處的位設置為指定的值。
          public void clear(int pos): 位置pos的字位設置為false。
          public void clear() : 將此 BitSet 中的所有位設置為 false。
          public int cardinality() 返回此 BitSet 中設置為 true 的位數。
          public boolean get(int pos): 返回位置是pos的字位值。
          public void and(BitSet other): other同該字位集進行與操作,結果作為該字位集的新值。
          public void or(BitSet other): other同該字位集進行或操作,結果作為該字位集的新值。
          public void xor(BitSet other): other同該字位集進行異或操作,結果作為該字位集的新值。
          public void andNot(BitSet set) 清除此 BitSet 中所有的位,set - 用來屏蔽此 BitSet 的 BitSet
          public int size(): 返回此 BitSet 表示位值時實際使用空間的位數。
          public int length() 返回此 BitSet 的“邏輯大小”:BitSet 中最高設置位的索引加 1。
          public int hashCode(): 返回該集合Hash 碼, 這個碼同集合中的字位值有關。
          public boolean equals(Object other): 如果other中的字位同集合中的字位相同,返回true。
          public Object clone() 克隆此 BitSet,生成一個與之相等的新 BitSet。
          public String toString() 返回此位 set 的字符串表示形式。

          例1:標明一個字符串中用了哪些字符
          import java.util.BitSet;
          public class WhichChars{
             private BitSet used = new BitSet();
             public WhichChars(String str){
                for(int i=0;i< str.length();i++)
                  used.set(str.charAt(i));  // set bit for char
             }
              public String toString(){
                   String desc="[";
                   int size=used.size();
                    for(int i=0;i< size;i++){
                       if(used.get(i))
                           desc+=(char)i;
                      }
                       return desc+"]";
                   }
              public static void main(String args[]){
                  WhichChars w=new WhichChars("How do you do");
                  System.out.println(w);
              }
             }
          運行:
          C:\work>java WhichChars

          [ Hdouwy]


          2. java.util.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

          這樣就省下了很大空間。

          看看測試例子

          1. package com;
          2. import java.util.BitSet;
          3. public class MainTestThree {
          4. /**
          5. * @param args
          6. */
          7. public static void main(String[] args) {
          8. BitSet bm=new BitSet();
          9. System.out.println(bm.isEmpty()+"--"+bm.size());
          10. bm.set(0);
          11. System.out.println(bm.isEmpty()+"--"+bm.size());
          12. bm.set(1);
          13. System.out.println(bm.isEmpty()+"--"+bm.size());
          14. System.out.println(bm.get(65));
          15. System.out.println(bm.isEmpty()+"--"+bm.size());
          16. bm.set(65);
          17. System.out.println(bm.isEmpty()+"--"+bm.size());
          18. }
          19. }

          輸出:
          true--64
          false--64
          false--64
          false
          false--64
          false--128

          說明默認的構造函數聲明一個64位的BitSet,值都是false。
          如果你要用的位超過了默認size,它會再申請64位,而不是報錯。

          1. package com;
          2. import java.util.BitSet;
          3. public class MianTestFour {
          4. /**
          5. * @param args
          6. */
          7. public static void main(String[] args) {
          8. BitSet bm1=new BitSet(7);
          9. System.out.println(bm1.isEmpty()+"--"+bm1.size());
          10. BitSet bm2=new BitSet(63);
          11. System.out.println(bm2.isEmpty()+"--"+bm2.size());
          12. BitSet bm3=new BitSet(65);
          13. System.out.println(bm3.isEmpty()+"--"+bm3.size());
          14. BitSet bm4=new BitSet(111);
          15. System.out.println(bm4.isEmpty()+"--"+bm4.size());
          16. }
          17. }


          輸出:
          true--64
          true--64
          true--128
          true--128

          說明你申請的位都是以64為倍數的,就是說你申請不超過一個64的就按64算,超過一個不超過
          2個的就按128算。

          1. package com;
          2. import java.util.BitSet;
          3. public class MainTestFive {
          4. /**
          5. * @param args
          6. */
          7. public static void main(String[] args) {
          8. int[] shu={2,42,5,6,6,18,33,15,25,31,28,37};
          9. BitSet bm1=new BitSet(MainTestFive.getMaxValue(shu));
          10. System.out.println("bm1.size()--"+bm1.size());
          11. MainTestFive.putValueIntoBitSet(shu, bm1);
          12. printBitSet(bm1);
          13. }
          14. //初始全部為false,這個你可以不用,因為默認都是false
          15. public static void initBitSet(BitSet bs){
          16. for(int i=0;i<bs.size();i++){
          17. bs.set(i, false);
          18. }
          19. }
          20. //打印
          21. public static void printBitSet(BitSet bs){
          22. StringBuffer buf=new StringBuffer();
          23. buf.append("[\n");
          24. for(int i=0;i<bs.size();i++){
          25. if(i<bs.size()-1){
          26. buf.append(MainTestFive.getBitTo10(bs.get(i))+",");
          27. }else{
          28. buf.append(MainTestFive.getBitTo10(bs.get(i)));
          29. }
          30. if((i+1)%8==0&&i!=0){
          31. buf.append("\n");
          32. }
          33. }
          34. buf.append("]");
          35. System.out.println(buf.toString());
          36. }
          37. //找出數據集合最大值
          38. public static int getMaxValue(int[] zu){
          39. int temp=0;
          40. temp=zu[0];
          41. for(int i=0;i<zu.length;i++){
          42. if(temp<zu[i]){
          43. temp=zu[i];
          44. }
          45. }
          46. System.out.println("maxvalue:"+temp);
          47. return temp;
          48. }
          49. //放值
          50. public static void putValueIntoBitSet(int[] shu,BitSet bs){
          51. for(int i=0;i<shu.length;i++){
          52. bs.set(shu[i], true);
          53. }
          54. }
          55. //true,false換成1,0為了好看
          56. public static String getBitTo10(boolean flag){
          57. String a="";
          58. if(flag==true){
          59. return "1";
          60. }else{
          61. return "0";
          62. }
          63. }
          64. }



          輸出:
          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.

          出現的次數這個信息就丟了


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 郎溪县| 镶黄旗| 古交市| 忻城县| 南澳县| 延安市| 武强县| 禹城市| 云阳县| 寻乌县| 区。| 嘉定区| 玉林市| 井研县| 三门县| 北宁市| 普宁市| 喜德县| 华蓥市| 扶沟县| 三门县| 揭西县| 肇源县| 林西县| 达日县| 平南县| 睢宁县| 广丰县| 盘山县| 乌苏市| 开封县| 五台县| 泽普县| 杭州市| 临洮县| 辉县市| 长治县| 龙州县| 三穗县| 庆城县| 滦平县|