假设我有一个List<Integer> ls
我知道它的长度,我们可以为 bytebuffer 分配 length*4 字节并使用 put 直接将 ls 读入缓冲区吗?
最佳答案
这应该可以满足您的要求:
ByteBuffer buffer = ByteBuffer.allocate(ls.size()*4);
for (Integer i: ls)
buffer.putInt(i);
一个警告:此函数假设您的列表不包含任何 null 条目。
我认为你不能做得比这更好,因为 Integer
中 ls
对象的底层数组是这些 Integer
对象的引用(指针)数组,而不是它们包含的 int
值。实际的 Integer
对象将以某种随机顺序驻留在内存中,大致由它们的创建时间决定。因此,您不太可能找到一些连续的内存块,其中包含您需要复制到 ByteBuffer
中的数据(我认为这就是您所说的“直接读取”它的意思。)。因此,像使用 sun.misc.Unsafe
这样的东西可能无法帮助您。
即使您有 int[]
而不是 List<Integers>
,您也可能无法可靠地将数据直接从内存读取到 ByteBuffer
中,因为 64 位计算机上的某些 JVM 会对齐 64 位地址上的所有值 -更快访问的位置,这会导致 ints
之间出现“间隙”。然后是 endianness 的问题,这可能因平台而异......
编辑:
嗯...我刚刚看了一下它将调用的 OpenJDK source-code for the putInt()-function...这是一个可怕的困惑的子函数调用。如果“sun”实现同样“糟糕”,如果您正在寻找性能,您可能最好自己进行转换(使用移位和二进制操作)...最快的可能是转换您的 Integers
到 byte[]
,然后使用 ByteBuffer.wrap(...)
如果您需要答案为 ByteBuffer
。如果您需要代码,请告诉我...
关于java - 我们可以在java中直接将对象读入字节缓冲区吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23036271/