2017-07-06 98 views
1

這是我的代碼。我想要做的是使用BitSet處理來自我的ByteBuffer的字節。字節緩衝區從DynamoDB加載(隨着DynamoDBMapper)爲什麼我的BitSet的大小爲0?

ByteBuffer buffer = ....... 
    System.out.println("Array length is " + buffer.array().length); 
    BitSet bitSet = BitSet.valueOf(buffer.array()); 
    System.out.println("Bit set size is " + bitSet.size()); 

當我執行我的代碼,我看到我的ByteBuffer的陣列長度爲6100,這意味着它是由6100個字節支持。這些字節全部爲0。但是我也看到位集大小是0.這對我來說沒有意義(大小應該是6100 * 8)。

我查看了valueOf的文檔以及「返回包含給定字節數組中所有位的新位集」的說明。對於我想要做的事情是有意義的。

我犯的第一個錯誤是使用位集的長度。長度爲0,這是合理的,因爲所有的位都是0。大小函數「返回此BitSet實際使用的空間位數,以表示位值。」尺寸函數不應該在這裏返回6100 * 8嗎?

更新:我只是試圖把全1到字節緩衝區,現在我得到的7000數組長度和7232

回答

2

BitSet位集合的大小沒有實現直接保持同等大小的緩衝區的數組傳入以初始化它。相反,它在內部維護足夠的緩衝區空間來跟蹤打開的最高位。對於任何比這更高的位,BitSet#get等方法假定如果傳遞比當前緩衝區空間中維持的位索引更高的位,則該位必須關閉。

JavaDocs中有幾個關於「大小」或「長度」的相關語句。來自類級別的JavaDocs BitSet

每個位集都有一個當前大小,它是該位集當前正在使用的空間位數。請注意,大小與位集的實現有關,所以它可能隨實現而改變。位集的長度與位集的邏輯長度有關,並且與實現無關地定義。

BitSet#length

返回此BitSet的「邏輯大小」:在BitSet中加一的最高設置位的索引。如果BitSet不包含設定位,則返回零。

(另請注意,在關閉所有位的極端情況下,它返回零。)

BitSet#size

通過此BitSet返回實際使用空間的位數代表比特值。該集合中的最大元素是大小 - 第一個元素。

如果你有興趣在更深的下潛,我也建議看OpenJDK的代碼BitSet

http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/3462d04401ba/src/share/classes/java/util/BitSet.java

有趣的部分是set,可動態擴展的需要設置緩衝空間如果所請求的位索引超出當前緩衝區容量(words成員變量),則返回,該代碼返回false

+0

那麼你會推薦處理bytebuffer並使用位操作呢? – committedandroider

+1

@committedandroider,我認爲這取決於你的具體需求。您當然可以編寫自己的邏輯來直接在「ByteBuffer」內計算正確的偏移量,並測試某個位是關閉還是打開。但是,如果您需要將這些數據長時間保存在內存中,並且數據集很大,那麼'BitSet'的更緊湊表示可能有助於減少應用程序的內存佔用量。 –

+0

「相反,它在內部維護着足夠的緩衝空間來跟蹤最高位」。我讀過這個,但有6100字節(全0),它怎麼可能有0的大小? – committedandroider

相關問題