Как мне преобразовать ArrayList UUID в ByteArray? - PullRequest
0 голосов
/ 06 августа 2020
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)
    }
}

У меня есть приведенный выше код для преобразования UUID в ByteArray и его обратного преобразования, но мне также нужно иметь возможность преобразовать ArrayList в ByteArray и преобразовать его обратно. Как мне это сделать? Если вам интересно, зачем мне это делать, потому что мне нужно хранить HashMap

1 Ответ

1 голос
/ 06 августа 2020

Вы можете просто использовать оператор + для объединения независимых байтовых массивов 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
    // 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)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...