为什么ByteBuffer不保留putDouble和getDouble的索引?

时间:2018-02-27 18:21:47

标签: java bytebuffer

在以下场景中,我很难理解ByteBuffer的语义:

int sizeOfDouble = 8;
int numberOfDoubles = 4;
ByteBuffer testBuf = ByteBuffer.allocateDirect(sizeOfDouble*numberOfDoubles);

testBuf.putDouble(0, 1.0);
testBuf.putDouble(1, 2.0);
testBuf.putDouble(2, 3.0);
testBuf.putDouble(3, 4.0);

for (int i = 0; i < numberOfDoubles; ++i) {
    System.out.println("testBuf[" + i + "]: " + testBuf.getDouble(i));
}

我希望看到我刚刚放入ByteBuffer的值打印到屏幕上。相反,我得到了这个输出:

testBuf[0]: 4.959404759574682E-4
testBuf[1]: 32.50048828125
testBuf[2]: 32.125
testBuf[3]: 4.0

第三个索引的值似乎符合我的预期:4.0。但为什么值和索引0,1和2与我插入的值(分别为1.0,2.0和3.0)不匹配?

我怀疑我误解了ByteBuffer的工作方式,但我无法在javadoc中找到它。

3 个答案:

答案 0 :(得分:5)

这是因为您的代码将索引视为double s数组中的索引。初始写入成功完成;然后第二个写入除了第一个之外的字节;第三个写再次覆盖字节,依此类推。

第一个参数表示缓冲区内字节数组的索引,因此需要将其乘以4.0

sizeOfDouble

Demo.

答案 1 :(得分:4)

putDouble()的第一个参数是一个字节的索引,而不是double的索引。所以你放的双打是重叠的;第四个是最后写的,所以它被保留了,但之前的那个被破坏了。

要获得所需内容,您需要在编写和阅读时将索引乘以Double.BYTES

以下按预期方式工作:

int numberOfDoubles = 4;
ByteBuffer testBuf = ByteBuffer.allocateDirect(Double.BYTES*numberOfDoubles);

testBuf.putDouble(0, 1.0);
testBuf.putDouble(Double.BYTES, 2.0);
testBuf.putDouble(Double.BYTES * 2, 3.0);
testBuf.putDouble(Double.BYTES * 3, 4.0);

for (int i = 0; i < numberOfDoubles; ++i) {
    System.out.println("testBuf[" + i + "]: " + testBuf.getDouble(i * Double.BYTES));
}

答案 2 :(得分:1)

由于您只使用double值,因此可以使用DoubleBuffer代替:

int numberOfDoubles = 4;
DoubleBuffer testBuf = DoubleBuffer.allocate(numberOfDoubles);

testBuf.put(0, 1.0);
testBuf.put(1, 2.0);
testBuf.put(2, 3.0);
testBuf.put(3, 4.0);

for (int i = 0; i < numberOfDoubles; ++i) {
    System.out.println("testBuf[" + i + "]: " + testBuf.get(i));
}

或者您可以使用ByteBuffer包裹DoubleBuffer

int sizeOfDouble = Double.BYTES;
int numberOfDoubles = 4;
ByteBuffer testBuf = ByteBuffer.allocateDirect(sizeOfDouble*numberOfDoubles);
DoubleBuffer dblBuf = testBuf.asDoubleBuffer();

dblBuf.put(0, 1.0);
dblBuf.put(1, 2.0);
dblBuf.put(2, 3.0);
dblBuf.put(3, 4.0);

for (int i = 0; i < numberOfDoubles; ++i) {
    System.out.println("dblBuf[" + i + "]: " + dblBuf.get(i));
}
for (int i = 0; i < testBuf.limit(); ++i) {
    System.out.println("testBuf[" + i + "]: " + testBuf.get(i));
}

输出

dblBuf[0]: 1.0
dblBuf[1]: 2.0
dblBuf[2]: 3.0
dblBuf[3]: 4.0
testBuf[0]: 63
testBuf[1]: -16
testBuf[2]: 0
testBuf[3]: 0
testBuf[4]: 0
testBuf[5]: 0
testBuf[6]: 0
testBuf[7]: 0
testBuf[8]: 64
testBuf[9]: 0
testBuf[10]: 0
testBuf[11]: 0
testBuf[12]: 0
testBuf[13]: 0
testBuf[14]: 0
testBuf[15]: 0
testBuf[16]: 64
testBuf[17]: 8
testBuf[18]: 0
testBuf[19]: 0
testBuf[20]: 0
testBuf[21]: 0
testBuf[22]: 0
testBuf[23]: 0
testBuf[24]: 64
testBuf[25]: 16
testBuf[26]: 0
testBuf[27]: 0
testBuf[28]: 0
testBuf[29]: 0
testBuf[30]: 0
testBuf[31]: 0