Kotlinx Library
Extended Kotlin libraries for advanced functionality
🚀 What is Kotlinx Library?
Kotlinx libraries extend Kotlin with powerful features like coroutines for async programming, serialization for data handling, and datetime utilities. These official extensions make complex tasks simple and efficient.
import kotlinx.coroutines.*
// Asynchronous programming made easy
suspend fun fetchData(): String {
delay(1000) // Simulate network call
return "Data loaded!"
}
runBlocking {
println("Loading...")
val result = fetchData()
println(result) // "Data loaded!" after 1 second
}
Kotlinx Libraries
Coroutines
Asynchronous programming made simple
launch {
delay(1000)
println("Hello!")
}
Serialization
Convert objects to JSON and back
@Serializable
data class User(val name: String)
Json.encodeToString(user)
Datetime
Modern date and time handling
val now = Clock.System.now()
val date = LocalDate(2024, 1, 15)
Collections
Immutable collections and utilities
val list = persistentListOf(1, 2, 3)
val updated = list.add(4)
🔹 Kotlinx Coroutines
Write asynchronous code that looks synchronous:
import kotlinx.coroutines.*
// Simulate network operations
suspend fun fetchUserData(userId: Int): String {
delay(1000) // Simulate network delay
return "User data for ID: $userId"
}
suspend fun fetchUserPosts(userId: Int): List {
delay(800) // Simulate network delay
return listOf("Post 1", "Post 2", "Post 3")
}
fun main() = runBlocking {
println("Starting data fetch...")
// Sequential execution
val startTime = System.currentTimeMillis()
val userData = fetchUserData(123)
val userPosts = fetchUserPosts(123)
val sequentialTime = System.currentTimeMillis() - startTime
println("Sequential results:")
println("- $userData")
println("- Posts: $userPosts")
println("- Time taken: ${sequentialTime}ms")
// Parallel execution with async
val startTime2 = System.currentTimeMillis()
val userDataDeferred = async { fetchUserData(456) }
val userPostsDeferred = async { fetchUserPosts(456) }
val userData2 = userDataDeferred.await()
val userPosts2 = userPostsDeferred.await()
val parallelTime = System.currentTimeMillis() - startTime2
println("\nParallel results:")
println("- $userData2")
println("- Posts: $userPosts2")
println("- Time taken: ${parallelTime}ms")
}
Output:
Starting data fetch...
Sequential results:
- User data for ID: 123
- Posts: [Post 1, Post 2, Post 3]
- Time taken: 1800ms
Parallel results:
- User data for ID: 456
- Posts: [Post 1, Post 2, Post 3]
- Time taken: 1000ms
🔹 Kotlinx Serialization
Convert Kotlin objects to JSON and other formats:
import kotlinx.serialization.*
import kotlinx.serialization.json.*
@Serializable
data class Product(
val id: Int,
val name: String,
val price: Double,
val inStock: Boolean = true,
val tags: List = emptyList()
)
@Serializable
data class Order(
val orderId: String,
val products: List,
val customerEmail: String
)
fun main() {
// Create sample data
val products = listOf(
Product(1, "Laptop", 999.99, true, listOf("electronics", "computers")),
Product(2, "Mouse", 29.99, false, listOf("electronics", "accessories"))
)
val order = Order("ORD-123", products, "[email protected]")
// Serialize to JSON
val json = Json { prettyPrint = true }
val jsonString = json.encodeToString(order)
println("Order as JSON:")
println(jsonString)
// Deserialize from JSON
val deserializedOrder = json.decodeFromString(jsonString)
println("\nDeserialized order:")
println("Order ID: ${deserializedOrder.orderId}")
println("Customer: ${deserializedOrder.customerEmail}")
println("Products: ${deserializedOrder.products.size}")
// Working with individual products
deserializedOrder.products.forEach { product ->
println("- ${product.name}: $${product.price} (${if (product.inStock) "In Stock" else "Out of Stock"})")
}
}
Output:
Order as JSON:
{
"orderId": "ORD-123",
"products": [
{
"id": 1,
"name": "Laptop",
"price": 999.99,
"inStock": true,
"tags": ["electronics", "computers"]
}
],
"customerEmail": "[email protected]"
}
Deserialized order:
Order ID: ORD-123
Customer: [email protected]
Products: 2
- Laptop: $999.99 (In Stock)
- Mouse: $29.99 (Out of Stock)
🔹 Kotlinx Datetime
Modern, multiplatform date and time handling:
import kotlinx.datetime.*
fun main() {
// Current time
val now = Clock.System.now()
println("Current instant: $now")
// Local date and time
val localDateTime = now.toLocalDateTime(TimeZone.currentSystemDefault())
println("Local date time: $localDateTime")
// Working with dates
val today = Clock.System.todayIn(TimeZone.currentSystemDefault())
val birthday = LocalDate(1990, 5, 15)
val tomorrow = today.plus(1, DateTimeUnit.DAY)
println("Today: $today")
println("Birthday: $birthday")
println("Tomorrow: $tomorrow")
// Date calculations
val daysBetween = today.daysUntil(birthday.plus(DatePeriod(years = 34)))
println("Days until next birthday: $daysBetween")
// Time zones
val utcTime = Clock.System.now()
val newYorkTime = utcTime.toLocalDateTime(TimeZone.of("America/New_York"))
val tokyoTime = utcTime.toLocalDateTime(TimeZone.of("Asia/Tokyo"))
println("UTC: ${utcTime.toLocalDateTime(TimeZone.UTC)}")
println("New York: $newYorkTime")
println("Tokyo: $tokyoTime")
// Duration calculations
val startTime = Clock.System.now()
// Simulate some work
Thread.sleep(100)
val endTime = Clock.System.now()
val duration = endTime - startTime
println("Operation took: ${duration.inWholeMilliseconds}ms")
// Formatting (basic example)
val date = LocalDate(2024, 12, 25)
println("Christmas 2024: ${date.dayOfWeek}, ${date.month} ${date.dayOfMonth}")
}
Output:
Current instant: 2024-01-15T10:30:45.123Z
Local date time: 2024-01-15T05:30:45.123
Today: 2024-01-15
Birthday: 1990-05-15
Tomorrow: 2024-01-16
Days until next birthday: 120
UTC: 2024-01-15T10:30:45.123
New York: 2024-01-15T05:30:45.123
Tokyo: 2024-01-15T19:30:45.123
Operation took: 102ms
Christmas 2024: WEDNESDAY, DECEMBER 25
🔹 Practical Example: API Client
Combine coroutines and serialization for a real API client:
import kotlinx.coroutines.*
import kotlinx.serialization.*
import kotlinx.serialization.json.*
@Serializable
data class User(val id: Int, val name: String, val email: String)
@Serializable
data class ApiResponse(val data: T, val status: String)
class ApiClient {
private val json = Json { ignoreUnknownKeys = true }
suspend fun fetchUser(id: Int): User {
delay(500) // Simulate network call
val jsonResponse = """
{
"data": {
"id": $id,
"name": "User $id",
"email": "[email protected]"
},
"status": "success"
}
""".trimIndent()
val response = json.decodeFromString>(jsonResponse)
return response.data
}
suspend fun fetchMultipleUsers(ids: List): List {
return ids.map { id ->
async { fetchUser(id) }
}.awaitAll()
}
}
fun main() = runBlocking {
val apiClient = ApiClient()
println("Fetching single user...")
val user = apiClient.fetchUser(1)
println("User: ${user.name} (${user.email})")
println("\nFetching multiple users in parallel...")
val startTime = System.currentTimeMillis()
val users = apiClient.fetchMultipleUsers(listOf(1, 2, 3, 4, 5))
val endTime = System.currentTimeMillis()
users.forEach { user ->
println("- ${user.name}: ${user.email}")
}
println("Fetched ${users.size} users in ${endTime - startTime}ms")
}
Output:
Fetching single user...
User: User 1 ([email protected])
Fetching multiple users in parallel...
- User 1: [email protected]
- User 2: [email protected]
- User 3: [email protected]
- User 4: [email protected]
- User 5: [email protected]
Fetched 5 users in 502ms