如何在Java中声明无限大小/动态的字节数组?

如何在Java中声明无限大小/动态的字节数组?,java,bytearray,Java,Bytearray,我正在声明一个字节数组,它的大小对我来说是未知的,因为它一直在更新,那么我如何才能声明无限大小/可变大小的字节数组呢?Java中的数组不是动态的。您可以改为使用列表 List<Byte> list = new ArrayList<Byte>(); List List=new ArrayList(); 由于自动装箱功能,您可以自由地将字节对象或基本字节添加到此列表。您最好使用ArrayList。填充时调整大小 List array=new ArrayList()不能声明

我正在声明一个字节数组,它的大小对我来说是未知的,因为它一直在更新,那么我如何才能声明无限大小/可变大小的字节数组呢?

Java中的数组不是动态的。您可以改为使用列表

List<Byte> list = new ArrayList<Byte>();
List List=new ArrayList();

由于自动装箱功能,您可以自由地将字节对象或基本字节添加到此列表。

您最好使用ArrayList。填充时调整大小


List array=new ArrayList()

不能声明无限大的数组,因为这需要无限大的内存。此外,所有分配调用都处理数字,而不是无限量

您可以分配一个按需调整大小的字节缓冲区。我相信最简单的选择是一个

有一个API使缓冲区的操作更容易,但您必须自己构建调整大小功能。最简单的方法是分配一个新的、更大的数组,在其中复制旧内容,并用新缓冲区替换旧缓冲区

其他答案提到使用某种类型的
列表。值得注意的是,如果创建一组
newbyte()
对象,则会显著增加内存消耗
Byte.valueOf
避开了这个问题,但您必须确保在整个代码中都能一致地使用它。如果你打算在很多地方使用这个列表,我可能会考虑编写一个简单的<>代码>清单>代码>装饰器,它可以对所有元素进行实习生操作。例如:

public class InterningList extends AbstractList<Byte>
{
    ...
    @Override
    public boolean add(Byte b) {
        return super.add(Byte.valueOf(b));
    }
    ...
}
公共类InterningList扩展了AbstractList
{
...
@凌驾
公共布尔加法(字节b){
返回super.add(Byte.valueOf(b));
}
...
}
这不是一个完整的(甚至不是经过测试的)示例,只是一个开始…

使用


列表的不同实现允许您在列表上执行不同的操作(例如不同的遍历策略、不同的性能等)

ArrayList的初始容量为10。您可以通过ArrayList(5000)进行更改。
ArrayList将在需要时将其大小加倍(它将创建新数组并将旧数组复制到新数组)。

显而易见的解决方案是使用ArrayList

但如果您需要性能或内存受限,这是一个糟糕的解决方案,因为它实际上并不存储字节,而是存储字节(即对象)

对于任何实际的应用程序,答案都很简单:您必须管理自己的字节数组,方法是根据需要使其增长。如果需要,您可以将其嵌入到特定类中:

public class AlmostInfiniteByteArray {

    private byte[] array;
    private int size;

    public AlmostInfiniteByteArray(int cap) {
        array = new byte[cap];
            size = 0;
    }

    public int get(int pos) {
        if (pos>=size) throw new ArrayIndexOutOfBoundsException();
        return array[pos];
    }

    public void set(int pos, byte val) {
        if (pos>=size) {
            if (pos>=array.length) {
                byte[] newarray = new byte[(pos+1)*5/4];
                System.arraycopy(array, 0, newarray, 0, size);
                array = newarray;
            }
            size = pos+1;
        }
        array[pos] = val;
    }
}

我会稍微改变别人的答案

创建一个LargeByteArray类来管理阵列。它将有get和set方法,等等,不管你需要什么

在幕后,该类将使用long保存当前长度,并使用ArrayList存储数组的内容

我会选择在ArrayList中存储字节[8192]或字节[16384]数组。这将在浪费的大小方面进行合理的权衡,并减少重新调整大小的需要

您甚至可以将数组设置为“稀疏”,即仅分配list.get(index/8192)条目(如果该框中存储了非零值)

在某些情况下,这样的结构可以为您提供更大的存储空间

您可以使用的另一种策略是在写入后压缩byte[]框,在读取前解压缩(使用LRU缓存进行读取),这可以允许存储两倍或两倍以上的可用ram。。。尽管这取决于压缩策略

之后,您可以查看将一些框分页到磁盘


这是我能找到的最接近无限数组的;-)

要定义不同长度的字节数组,只需使用apache
commons.io.IOUtils
库,而不是像

byte[] b=new byte[50];
您可以将输入流传递给
IOUtils
函数,该函数将在此输入流上执行读取功能,因此字节数组将具有所需的精确字节长度。 前


混乱..

正如普拉尚特已经说过的那样,你可以使用来自工件的IOUtils

这里有一小段可以解决这个任务(您需要IOUtils.toByteArray):


将允许写入动态字节数组。但是,删除、替换和插入等方法不可用。必须提取字节数组,然后直接对其进行操作。

由于没有在随机位置直接读取或写入字节的方法,ByteArrayOutputSream似乎不适合用作数组。@DenysSéguret
toByteArray()
!也要考虑弹簧,小心这个解决方案。我可能会确保所有对数组的写入都会进入一个内部程序-----如果您为每个元素创建一个新的字节,您的内存使用量将达到天文数字。@StevenSchlansker实例BTE需要通过自动装箱进行缓存。这也适用于同一范围内的整数。@JanDvorak:取决于JVM,但也不总是如此。例如,整数只能缓存从-127到128的数据,或者类似的数据。使用最新的Oracle JVM,您应该是安全的。显式
new
仍然会毁了你的一天。@StevenSchlansker字节范围内的整数=-128..127。JLSNote需要缓存字节的所有256个值和整数的相应值,尽管内存使用率仍然无法与
Byte[]
竞争。通过装箱,您仍然需要为每个元素提供一个完整的引用(字大小:在大多数体系结构中为32或64位),而不是每个元素8位。你需要4到8倍的空间。对于某些应用程序可以忽略,但对于其他应用程序,这会造成很大的伤害。那么
ArrayList
呢?
byte[] b = IOUtils.toByteArray(inpustream);
public class IOUtils {

private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;

public static byte[] toByteArray(InputStream input) throws IOException {
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    copy(input, output);
    return output.toByteArray();
}

public static int copy(InputStream input, OutputStream output)
        throws IOException {
    long count = copyLarge(input, output);
    if (count > Integer.MAX_VALUE) {
        return -1;
    }
    return (int) count;
}

public static long copyLarge(InputStream input, OutputStream output)
        throws IOException {
    byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
    long count = 0;
    int n = 0;
    while (-1 != (n = input.read(buffer))) {
        output.write(buffer, 0, n);
        count += n;
    }

    return count;

}
}