You can check if the ByteBuffer is backed by an array with hasArray and if so convert it back with array. That is fast, but not all buffers are backed that way.
You can always convert the ByteBuffer to an array, but that is hardly efficient. I would instead convert it to a buffer of whatever your basic data type is (unless it is bytes in which case you are already set), for example with asIntBuffer for int. Then compute indexes manually and access the elements with get(index).
For example with indexes x and y and z, the index can be computed as x + y*width + z*width*height where width is the x-dimension size and height the y-dimension size.
You may need to experiment to make sure that the way you compute your index is consistent with how the array does the job if you write to an array that you convert into a buffer.
EDIT: with allocateDirect your buffer is not backed by an array, so the second method is the one to use.