#c# #.net #spring #kotlin
Вопрос:
Я работаю с приложением .NET, которое хранит длинный список истинных/ложных значений в BitArray, который хранится на сервере SQL в виде двоичного(32) значения. Данные возвращаются из базы данных в виде байта[].
Я пытаюсь перенести проект в Котлин с помощью Spring. После долгих тестов и возни я, наконец, смог получить в Kotlin тот же массив, что и в BitArray в C#. Однако это решение кажется довольно сложным, просто чтобы получить массив true
/ false
значений из ByteArray.
Я уверен, что есть более чистый способ сделать это, но я все еще изучаю Котлин, и вот что я придумал:
fun convertByteArrayToBitArray(array: ByteArray): List<Boolean>{
val stringBuilder = StringBuilder()
array.forEach {
// Convert to Integer to convert to binaryString
var int = it.toInt()
// Because the array has signed values, convert to unsigned value. Either this or add
// '.takeLast(8)' to the end of the String.format call
if(int < 0) int = 256
// Convert to binary string padding with leading 0s
val binary = String.format("%8s", Integer.toBinaryString(int)).replace(" ", "0")
// Through testing, this binary value needs to be reversed to give the right values
// at the right index
stringBuilder.append(binary.reversed())
}
// Convert stringBuilder to CharArray then to List of true/false values
return stringBuilder.toString().toCharArray().map {
Integer.parseInt(it.toString()) == 1
}
}
Ответ №1:
Если вам не нужен мультиплатформенный код, вы можете использовать набор битов из Java stdlib:
val bytes = byteArrayOf(0x11, 0x11)
val bits = BitSet.valueOf(bytes)
println(bits[0]) // true
println(bits[1]) // false
println(bits[4]) // true
println(bits[5]) // false
println(bits[8]) // true
println(bits[9]) // false
val bytes2 = bits.toByteArray()
Он хранит данные в литтл-эндиане. Если я правильно прочитал ваш код, он также использует файл.
Если вам нужно List<Boolean>
конкретно, например, потому, что часть вашего кода уже зависит от него, вы можете конвертировать между BitSet
и List<Boolean>
так:
fun BitSet.toBooleanList() = List(length()) { this[it] }
fun List<Boolean>.toBitSet() = BitSet(size).also { bitSet ->
forEachIndexed { i, item ->
bitSet.set(i, item)
}
}
Просто обратите List<Boolean>
внимание, что это очень неэффективно для памяти.
Комментарии:
1. Вау… Я почти чувствую себя глупо из-за того, насколько простым было решение для этого. Большое спасибо!
2. И если вам действительно нужен логический список…
fun BitSet.toBooleanList() = List<Boolean>(length(), ::get)
3. @Tenfour04 Да, я уже добавил это 😉
4. Ой. Но вам нужно использовать
length()
вместоsize()
этого .5. Да, вы правы. На самом деле, я думаю, что это было бы лучше всего получить
16
при преобразовании из массива в два байта, но я думаюBitSet
, что такая информация не хранится. Тогдаlength()
имеет больше смысла, чемsize()
. Спасибо.