簡體   English   中英

什么是Java中可調整大小,隨機訪問,高效的字節向量類?

[英]What's a good resizable, random access, efficient byte vector class in Java?

我正在嘗試找到一個用於在Java中存儲字節向量的類,它支持:隨機訪問(所以我可以在任何地方獲取或設置一個字節),調整大小(所以我可以將內容附加到最后,或者手動更改大小),合理的效率(我可能在這些東西中存儲兆字節的數據),都在內存中(我沒有文件系統)。 有什么建議?

到目前為止候選人是:

  • byte[] 不可調整大小。
  • java.util.Vector<Byte> 邪惡。 也痛苦無效。
  • java.io.ByteArrayOutputStream 不是隨機訪問。
  • java.nio.ByteBuffer 不可調整大小。
  • org.apache.commons.collections.primitives.ArrayByteList 不可調整大小。 這很奇怪,因為它會自動調整大小,如果你添加東西,你就不能明確地改變大小!
  • java.nio.channels.FileChannel純RAM實現。 找不到一個。 (記住我沒有文件系統。)
  • Apache Commons VFS和RAM文件系統。 如果我必須,但我真的喜歡更重的東西......

這似乎是一個奇怪的遺漏,我相信我肯定錯過了某個地方。 我只想弄清楚什么。 我錯過了什么?

我認為,它包裝大量的組塊的類byte[]數組作為元素ArrayListVector

使每個塊成為1024字節的倍數,因此訪問器函數可以使用index >> 10來訪問ArrayList的右元素,然后index & 0x3ff來訪問該數組的特定字節元素。

這將避免浪費將每個byte視為Byte對象,浪費在最后一個塊末尾留下的任何東西。

在這些情況下,我只是初始化對合理長度數組的引用,當它變得太小時,通過調用Arrays.copyOf()創建並將其復制到更大的數組。 例如:

byte[] a = new byte[16];
if (condition) {
    a = Arrays.copyOf(a, a.length*2);
}

如果需要,我們可以將它包裝在一個類中......

ArrayList比Vector更有效,因為它沒有同步。

為了提高效率,您可以從一個不錯的初始容量開始。 看到構造函數:

ArrayList(int initialCapacity) 

我認為默認值只有16,而你可能需要更大的尺寸。

盡管看起來如此, ArrayList即使擁有一百萬條記錄也非常高效! 我寫了一個小的測試程序,在沒有聲明初始容量的情況下向ArrayList添加了一百萬條記錄,在我的Linux,5年前的筆記本電腦(Core 2 T5200 cpu)上,只需要大約100毫秒來填充整個列表。 如果我聲明一個100萬字節的初始空間需要大約60-80毫秒,但如果我聲明10,000個項目它可能需要大約130-160毫秒,所以可能最好不要聲明任何東西,除非你可以很好地猜測空間需要。

關於內存使用的問題,它需要大約8 Mb的內存,我認為這是完全合理的,除非你正在編寫手機軟件。

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import org.obliquid.util.StopWatch;

public class ArrayListTest {

        public static void main(String args[]) {
                System.out.println("tot=" + Runtime.getRuntime().totalMemory() 
                     + " free=" + Runtime.getRuntime().freeMemory());
                StopWatch watch = new StopWatch();
                List<Byte> bytes = new ArrayList<Byte>();
                for (int i = 0; i < 1000000; i++) {
                        bytes.add((byte) (i % 256 - 128));
                }
                System.out.println("Elapsed: " 
                     + watch.computeElapsedMillisSeconds());
                System.out.println("tot=" + Runtime.getRuntime().totalMemory() 
                     + " free=" + Runtime.getRuntime().freeMemory());
        }
}

正如預期的那樣,Vector在160-200ms的范圍內表現稍差。

示例輸出,未指定起始大小和ArrayList實現。

tot=31522816 free=31023176
Elapsed: 74
tot=31522816 free=22537648

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM