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: Checking Membership in a Range
val range = 1..10
println(5 in range) // true
println(15 in range) // false
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")
}
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 |