Miek Miek - 5 months ago 19
Java Question

Casting to floats from Java Object

I am trying to understand the process for obtaining the value for thousands of float data types being past as a Java object(byte array)

We use a similar methodology in c++ where we store the data in a massive char array and we simply cast it to a float array using reinterpret_cast and do work on the float array:

// Get the data.
char *data = signalBlock->getData();
float *eegData = reinterpret_cast<float*>(data);


In Objective C we store the data in an NSData object and we are able to cast the data with this simple routine:

// Get the signal Data.
NSData* data = signalBlock.data;
float* floatData = (float*)malloc(dataBlockSize);
[data getBytes:floatData length:dataBlockSize];


I would like to know if this is proper for Java or if there is a more efficient way to do this. How can I cast the entire object into a float array?

byte[] dataBytes = (byte[])(block.data); // block.data is a java object

ByteBuffer dataBuffer = ByteBuffer.wrap(dataBytes);
dataBuffer.order(ByteOrder.LITTLE_ENDIAN);


for(int i = 0; i < 200000; i+=4){

float fVal = dataBuffer.getFloat(i);
System.out.println(fVal);
}


Thank You.

Answer

You can not "cast" the data into a float[] array. But you could use ByteBuffer#asFloatBuffer and then fetch the data using the relative bulk get method:

byte[] dataBytes = ...;

ByteBuffer dataBuffer = ByteBuffer.wrap(dataBytes);
dataBuffer.order(ByteOrder.LITTLE_ENDIAN);

FloatBuffer floatBuffer = dataBuffer.asFloatBuffer();
float floatArray[] = new float[dataBytes.length / Float.BYTES];
floatBuffer.get(floatArray);

or, if you prefer the short, fluent style:

byte[] dataBytes = ....;
float floatArray[] = new float[dataBytes.length / Float.BYTES];
ByteBuffer dataBuffer = ByteBuffer.wrap(dataBytes)
    .order(ByteOrder.LITTLE_ENDIAN)
    .asFloatBuffer()
    .get(floatArray);

This is a tad more convenient and elegant than fetching the floats individually from the ByteBuffer, and it is likely more efficient. (I didn't do a dedicated benchmark for this, but certain bulk methods are said to be "... potentially much more efficient" than the non-bulk methods in the JavaDocs)


Edit: A side note that may be relevant for the future: It is not possible to "cast" the data into a float[] array yet. But in fact, something similar (!) is tackled in project Panama: http://hg.openjdk.java.net/panama/panama/jdk/rev/42bf13af7c8b (I did not yet study the commits in detail, but the goal basically seems to be to hand over an "arbitrary" memory region to the JVM, and let it appear like a float[] array, for example.

Comments