Skip to main content

Working with Kotlin Data Types

1. Using Primitive Types

Type Description Size Default Value
Byte Signed 8-bit integer 1 byte 0
Short Signed 16-bit integer 2 bytes 0
Int Signed 32-bit integer 4 bytes 0
Long Signed 64-bit integer 8 bytes 0L
Float 32-bit IEEE 754 single-precision floating point 4 bytes 0.0f
Double 64-bit IEEE 754 double-precision floating point 8 bytes 0.0
Char 16-bit Unicode character 2 bytes '\u0000'
Boolean Logical value (true or false) 1 bit false

Example: Declaring and Using Primitive Types

fun main() {
    val byteValue: Byte = 100
    val shortValue: Short = 2000
    val intValue: Int = 100000
    val longValue: Long = 9000000000L
    val floatValue: Float = 3.14f
    val doubleValue: Double = 2.71828
    val charValue: Char = 'A'
    val booleanValue: Boolean = true

    println("Byte: $byteValue")
    println("Short: $shortValue")
    println("Int: $intValue")
    println("Long: $longValue")
    println("Float: $floatValue")
    println("Double: $doubleValue")
    println("Char: $charValue")
    println("Boolean: $booleanValue")
}

2. Working with String Type

Property Description Example
String Represents a sequence of characters in Kotlin "Hello, World!"
String.length Property to get the length of a string "Kotlin".length → 6
String.isEmpty() Checks if the string is empty "".isEmpty() → true
String.isNotBlank() Checks if the string is not blank (contains at least one non-whitespace character) " ".isNotBlank() → false
String.indexOf() Finds the index of a substring or character "Kotlin".indexOf('t') → 4
String.substring() Extracts a substring from the string "Kotlin".substring(0, 3) → "Kot"
String.replace() Replaces occurrences of a substring with another "Kotlin".replace("K", "k") → "kotlin"
String.toUpperCase() Converts the string to uppercase "kotlin".toUpperCase() → "KOTLIN"
String.toLowerCase() Converts the string to lowercase "KOTLIN".toLowerCase() → "kotlin"
String.trim() Removes leading and trailing whitespace " Kotlin ".trim() → "Kotlin"

Example: String Concatenation

val greeting = "Hello"
val name = "Kotlin"
val message = greeting + " " + name + "!"
println(message) // Output: Hello Kotlin!

Example: String Templates

val language = "Kotlin"
val version = "1.9"
val message = "Welcome to $language version $version!"
println(message) // Output: Welcome to Kotlin version 1.9!

Example: Multiline Strings

val multiline = """
    This is a
    multiline string
    in Kotlin
""".trimIndent()
println(multiline)

Example: String Manipulation

val text = "Kotlin Programming"
val upperText = text.toUpperCase()
val reversedText = text.reversed()
val wordCount = text.split(" ").size
println(upperText) // Output: KOTLIN PROGRAMMING
println(reversedText) // Output: gnimmarorp nitoK
println(wordCount) // Output: 2

3. Understanding Number Conversions

Source Type Target Type Conversion Notes
Byte Short byte.toShort() Sign-extends the byte value
Byte Int byte.toInt() Sign-extends the byte value
Byte Long byte.toLong() Sign-extends the byte value
Short Int short.toInt() Sign-extends the short value
Short Long short.toLong() Sign-extends the short value
Int Long int.toLong() Sign-extends the int value
Float Double float.toDouble() Lossless conversion
Int Float int.toFloat() Potential precision loss
Long Float long.toFloat() Potential precision loss
Long Double long.toDouble() Potential precision loss

Example: Safe Conversion with Range Checks

fun safeByteToInt(byteValue: Byte): Int {
    return byteValue.toInt()
}

fun safeIntToShort(intValue: Int): Short {
    if (intValue !in Short.MIN_VALUE.toInt()..Short.MAX_VALUE.toInt()) {
        throw IllegalArgumentException("Value out of short range")
    }
    return intValue.toShort()
}

val byteVal: Byte = 100
val intVal: Int = safeByteToInt(byteVal)
println(intVal) // 100

val intFromRange: Int = 32767
val shortVal: Short = safeIntToShort(intFromRange)
println(shortVal) // 32767
Note: Kotlin performs automatic widening conversions (e.g., Byte to Int) but requires explicit casting for narrowing (e.g., Int to Byte). Use toX() methods for type conversions.

4. Using Arrays

Property Description Example
Array<T> Immutable array of fixed size val numbers = arrayOf(1, 2, 3)
MutableArray<T> Mutable array with dynamic size val mutableNumbers = mutableListOf(1, 2, 3)
Array<Int> Typed array for integers val intArray = IntArray(3) { 0 }

Example: Declaring and Initializing Arrays

val numbers = arrayOf(1, 2, 3, 4, 5)
val strings = arrayOf("hello", "world")
val emptyArray = Array(3) { "" }

Example: Modifying Mutable Arrays

val mutableNumbers = mutableListOf(1, 2, 3)
mutableNumbers.add(4) // Append element
mutableNumbers[0] = 10 // Modify element at index
mutableNumbers.removeAt(1) // Remove element at index

Example: Array Operations

val numbers = arrayOf(1, 2, 3, 4, 5)
val doubled = numbers.map { it * 2 }
val filtered = numbers.filter { it > 2 }
val sum = numbers.reduce { acc, num -> acc + num }
Note: Kotlin arrays are Array<T> and MutableList<T> for mutable collections.

5. Working with Nullable Types (Type?, safe calls)

Feature Description Example
Nullable Type Declaration Declares a type that can hold null values using ? var name: String? = null
Safe Call Operator Uses ?. to safely call methods or access properties on potentially null values val length = name?.length
Elvis Operator Provides a default value when the expression is null using ?: val length = name?.length ?: 0
Non-Null Assertion Asserts that a value is not null using !!, throws exception if null val length = name!!.length

Example: Safe Call Usage

fun main() {
    val user: User? = null
    val email = user?.email // Returns null if user is null
    println(email) // Prints: null
}

Example: Elvis Operator

fun main() {
    val user: User? = null
    val email = user?.email ?: "No email provided"
    println(email) // Prints: No email provided
}
Note: The safe call operator prevents NullPointerException by returning null instead of crashing.
Warning: Using !! can cause runtime exceptions if the value is null.

6. Implementing Ranges

Range Type Usage Description
IntRange 1..5 Represents a range of integers from 1 to 5 inclusive
CharRange 'a'..'z' Represents a range of characters from 'a' to 'z' inclusive
ClosedRange<T> 1.0..5.0 Generic range that includes both endpoints

Example: Using Ranges in a Loop

for (i in 1..5) {
    println(i)
}
// Output:
// 1
// 2
// 3
// 4
// 5

Example: Checking Membership in a Range

val range = 1..10
println(5 in range) // true
println(15 in range) // false

Example: Creating a Char Range

val charRange = 'A'..'Z'
println('M' in charRange) // true

7. Understanding Nothing Type

Property Description Usage
Nothing Represents a type that never returns a value Used in functions that always throw or loop infinitely

Example: Function Returning Nothing

fun throwError(): Nothing {
    throw IllegalArgumentException("Invalid input")
}

Example: Infinite Loop

fun infiniteLoop(): Nothing {
    while (true) {
        // Loop forever
    }
}
Note: Nothing is a subtype of every type, including Any?.

8. Using Any and Unit Types

Type Description Usage
Any Root of Kotlin class hierarchy. All classes inherit from Any. val obj: Any = "Hello"
Unit Represents a function that returns no meaningful value. Equivalent to void in Java. fun doSomething(): Unit { ... }

Example: Using Any for Polymorphism

fun processAny(value: Any) {
    when (value) {
        is String -> println("String length: ${value.length}")
        is Int -> println("Integer value: $value")
        else -> println("Unknown type")
    }
}

val list = listOf("Hello", 42, true)
list.forEach { processAny(it) }

Example: Using Unit in Functions

fun printMessage(msg: String): Unit {
    println("Message: $msg")
}

// Equivalent to:
fun printMessageAlt(msg: String) {
    println("Message: $msg")
}

printMessage("Hello World")

9. Working with Pair and Triple

Property Description Example
Pair Represents a tuple of two elements val pair = Pair("Hello", 42)
Triple Represents a tuple of three elements val triple = Triple("A", "B", "C")

Example: Creating and Using Pair

val person = Pair("Alice", 30)
println(person.first)  // Alice
println(person.second) // 30

Example: Creating and Using Triple

val coordinates = Triple(10.0, 20.0, 30.0)
println(coordinates.first)   // 10.0
println(coordinates.second)  // 20.0
println(coordinates.third)   // 30.0
Note: Pair and Triple are immutable and provide first, second, and third properties for accessing elements.

Example: Destructuring Pair and Triple

val (name, age) = Pair("Bob", 25)
val (x, y, z) = Triple(1, 2, 3)

println("$name is $age years old") // Bob is 25 years old
println("Coordinates: ($x, $y, $z)") // Coordinates: (1, 2, 3)

Example: Pair and Triple in Functions

fun getCoordinates(): Pair<Double, Double> {
    return Pair(10.5, 20.3)
}

fun getRGB(): Triple<Int, Int, Int> {
    return Triple(255, 128, 0)
}

val (lat, lng) = getCoordinates()
val (r, g, b) = getRGB()

println("Lat: $lat, Lng: $lng") // Lat: 10.5, Lng: 20.3
println("R: $r, G: $g, B: $b") // R: 255, G: 128, B: 0

10. Implementing Type Checks and Casts

Operation Syntax Description Notes
is obj is Type Checks if an object is of a specific type Returns Boolean
!is obj !is Type Checks if an object is NOT of a specific type Returns Boolean
as obj as Type Safe cast to a type (throws ClassCastException if fails) Use with as? for safe cast
as? obj as? Type Safe cast to a type (returns null if fails) Safer alternative to as

Example: Type Checking and Casting

val obj: Any = "Hello"
val str: String? = obj as? String
println(str) // Hello

val num: Int? = obj as? Int
println(num) // null

val isString = obj is String
println(isString) // true
Note: as? is preferred over as to avoid runtime exceptions.
Warning: Using as without checking can cause ClassCastException.
Type Check Safe Cast Unsafe Cast Use Case
obj is String obj as? String obj as String When you want to handle the failure case gracefully

Was this article helpful?