Home > Mobile >  Kotlin Equivalent to C# BitArray
Kotlin Equivalent to C# BitArray

Time:10-15

I'm working with a .NET application that stores a long list of true/false values into BitArray which gets stored in a SQL Server as a binary(32) value. The data comes back from the database as a byte[].

I'm trying to migrate the project over to Kotlin using Spring. After a lot of testing and messing around, I was finally able to get the same array in Kotlin that I do from the BitArray in C#. However, this solution seems like quite a kludge just to get an array of true/false values from a ByteArray.

I'm sure there's a cleaner way of going about this, but I'm still learning Kotlin and this is what I've come up with:

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
        }
}

CodePudding user response:

If you don't need multiplatform code, then you can use BitSet from the 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()

It stores the data in little endian. If I read your code correctly, it also uses LE.

If you need List<Boolean> specifically, for example because some of your code already depends on it, then you can convert between BitSet and List<Boolean> like this:

fun BitSet.toBooleanList() = List(length()) { this[it] }

fun List<Boolean>.toBitSet() = BitSet(size).also { bitSet ->
    forEachIndexed { i, item ->
        bitSet.set(i, item)
    }
}

Just note List<Boolean> is very memory-inefficient.

  • Related