英文:
How Do I Convert An ArrayList of UUID To A ByteArray?
问题
object UUIDConversion {
fun UUID.toByteArray(): ByteArray {
val byteBuffer = ByteBuffer.wrap(ByteArray(16))
byteBuffer.putLong(this.mostSignificantBits)
byteBuffer.putLong(this.leastSignificantBits)
return byteBuffer.array()
}
fun ByteArray.toUUID(): UUID {
val byteBuffer = ByteBuffer.wrap(this)
val mostSignificantBits = byteBuffer.long
val leastSignificantBits = byteBuffer.long
return UUID(mostSignificantBits, leastSignificantBits)
}
fun ArrayList<UUID>.toByteArray(): ByteArray {
val byteBuffer = ByteBuffer.wrap(ByteArray(size * 16))
for (uuid in this) {
byteBuffer.putLong(uuid.mostSignificantBits)
byteBuffer.putLong(uuid.leastSignificantBits)
}
return byteBuffer.array()
}
fun ByteArray.toUUIDList(): ArrayList<UUID> {
val byteBuffer = ByteBuffer.wrap(this)
val uuidList = ArrayList<UUID>()
while (byteBuffer.hasRemaining()) {
val mostSignificantBits = byteBuffer.long
val leastSignificantBits = byteBuffer.long
uuidList.add(UUID(mostSignificantBits, leastSignificantBits))
}
return uuidList
}
}
With these additional functions, you can now convert an ArrayList<UUID>
to a ByteArray
and vice versa using the toByteArray()
and toUUIDList()
functions.
英文:
object UUIDConversion {
fun UUID.toByteArray() : ByteArray {
val byteBuffer = ByteBuffer.wrap(ByteArray(16))
byteBuffer.putLong(this.mostSignificantBits)
byteBuffer.putLong(this.leastSignificantBits)
return byteBuffer.array()
}
fun ByteArray.toUUID() : UUID {
val byteBuffer = ByteBuffer.wrap(this)
val mostSignificantBits = byteBuffer.long
val leastSignificantBits = byteBuffer.long
return UUID(mostSignificantBits, leastSignificantBits)
}
}
I have the code above to convert a UUID to a ByteArray and convert it back but I also need to be able to convert an ArrayList<UUID> to a ByteArray and convert it back. How would I do that exactly? If you're wondering why I need to do this it's because I need to store a HashMap<UUID, ArrayList<UUID> in a key-value database and I need to convert it to a ByteArray and back to use it.
Java or Kotlin answers are both fine.
答案1
得分: 1
你可以只使用+
运算符来连接独立的UUID字节数组,如下所示:
val allUUIDs : ByteArray = listOfUUID.fold(ByteArray(0)) { buffer, uuid -> buffer + uuid.toByteArray() }
然而,如果你有很长的链条要转换,也许性能会显著下降。相反,你可以创建专门的方法来从/写入字节缓冲区:
import java.nio.ByteBuffer
import java.util.*
import kotlin.RuntimeException
fun ByteBuffer.readUUIDs(nbUUIDs : Int = remaining()/16) : Sequence<UUID> {
if (nbUUIDs <= 0) return emptySequence()
val nbBytes = nbUUIDs * 16
// 防御性复制 -> 结果序列与接收缓冲区独立
val defCpy = ByteArray(nbBytes)
// 切片(slice)是必需的,以保持源缓冲区不受影响
slice().get(defCpy)
val view = ByteBuffer.wrap(defCpy)
return (1..nbUUIDs).asSequence()
.map { UUID(view.long, view.long) }
}
fun List<UUID>?.write() : ByteBuffer? {
if (this == null || isEmpty()) return null;
val buffer = ByteBuffer.allocate(Math.multiplyExact(size, 16))
forEach { uuid ->
buffer.putLong(uuid.mostSignificantBits)
buffer.putLong(uuid.leastSignificantBits)
}
buffer.rewind()
return buffer
}
fun main() {
val uuids = (0..3).asSequence().map { UUID.randomUUID() }.toList()
val writtenUUIDs = uuids.write()
val uuidSequence = writtenUUIDs ?.readUUIDs() ?: throw RuntimeException("Bug")
// 请注意,现在我们可以对缓冲区进行任何操作,而不会影响序列
writtenUUIDs.getLong()
writtenUUIDs.putLong(-1)
val readBack = uuidSequence?.toList()
assert(uuids == readBack) { throw RuntimeException("Bug") }
println(uuids)
println(readBack)
}
英文:
You could just use +
operator to concatenate independant UUID byte arrays, like so:
val allUUIDs : ByteArray = listOfUUID.fold(ByteArray(0)) { buffer, uuid -> buffer + uuid.toByteArray() }
However, if you have long chains to convert, maybe performance could signicantly drop. Instead, you can make dedicated methods to read/write to/from byte buffers:
import java.nio.ByteBuffer
import java.util.*
import kotlin.RuntimeException
fun ByteBuffer.readUUIDs(nbUUIDs : Int = remaining()/16) : Sequence<UUID> {
if (nbUUIDs <= 0) return emptySequence()
val nbBytes = nbUUIDs * 16
// Defensive copy -> resulting sequence becomes independant from receiver buffer
val defCpy = ByteArray(nbBytes)
// slice is required to left source buffer untouched
slice().get(defCpy)
val view = ByteBuffer.wrap(defCpy)
return (1..nbUUIDs).asSequence()
.map { UUID(view.long, view.long) }
}
fun List<UUID>?.write() : ByteBuffer? {
if (this == null || isEmpty()) return null;
val buffer = ByteBuffer.allocate(Math.multiplyExact(size, 16))
forEach { uuid ->
buffer.putLong(uuid.mostSignificantBits)
buffer.putLong(uuid.leastSignificantBits)
}
buffer.rewind()
return buffer
}
fun main() {
val uuids = (0..3).asSequence().map { UUID.randomUUID() }.toList()
val writtenUUIDs = uuids.write()
val uuidSequence = writtenUUIDs ?.readUUIDs() ?: throw RuntimeException("Bug")
// Note that now, we can do whatever we want with the buffer. The sequence is not impacted
writtenUUIDs.getLong()
writtenUUIDs.putLong(-1)
val readBack = uuidSequence?.toList()
assert(uuids == readBack) { throw RuntimeException("Bug") }
println(uuids)
println(readBack)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论