Collections Operations trong Kotlin
🎯 Mục tiêu: Nắm vững các operations phổ biến trên collections: transform, filter, aggregate, và Sequence cho lazy evaluation.
💡 Tổng quan
Kotlin cung cấp bộ thư viện collection operations cực kỳ mạnh mẽ:
| Category | Functions |
|---|---|
| Transform | map, flatMap, zip, associate |
| Filter | filter, filterNot, take, drop, distinct |
| Aggregate | sum, max, min, average, reduce, fold |
| Group | groupBy, partition, chunked, windowed |
| Check | any, all, none, contains |
| Sort | sorted, sortedBy, sortedDescending |
🔄 Transform
val numbers = listOf(1, 2, 3, 4, 5)
// map
val doubled = numbers.map { it * 2 } // [2, 4, 6, 8, 10]
// flatMap
val nested = listOf(listOf(1, 2), listOf(3, 4))
val flattened = nested.flatMap { it } // [1, 2, 3, 4]
// zip
val a = listOf(1, 2, 3)
val b = listOf("a", "b", "c")
val zipped = a.zip(b) // [(1, a), (2, b), (3, c)]
val combined = a.zip(b) { num, str -> "$num$str" } // [1a, 2b, 3c]
// associate
val users = listOf("Alice", "Bob")
val userMap = users.associateWith { it.length } // {Alice=5, Bob=3}🔍 Filter
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// filter / filterNot
val even = numbers.filter { it % 2 == 0 } // [2, 4, 6, 8, 10]
val odd = numbers.filterNot { it % 2 == 0 } // [1, 3, 5, 7, 9]
// take / drop
val first3 = numbers.take(3) // [1, 2, 3]
val last3 = numbers.takeLast(3) // [8, 9, 10]
val skipFirst3 = numbers.drop(3) // [4, 5, 6, 7, 8, 9, 10]
// takeWhile / dropWhile
val takeSmall = numbers.takeWhile { it < 5 } // [1, 2, 3, 4]
val dropSmall = numbers.dropWhile { it < 5 } // [5, 6, 7, 8, 9, 10]
// distinct
val withDups = listOf(1, 2, 2, 3, 3, 3)
val unique = withDups.distinct() // [1, 2, 3]📊 Aggregate
val numbers = listOf(1, 2, 3, 4, 5)
println(numbers.sum()) // 15
println(numbers.average()) // 3.0
println(numbers.max()) // 5
println(numbers.min()) // 1
println(numbers.count()) // 5
// reduce (no initial value)
val sum = numbers.reduce { acc, n -> acc + n } // 15
// fold (with initial value)
val product = numbers.fold(1) { acc, n -> acc * n } // 120
val concat = numbers.fold("") { acc, n -> "$acc$n" } // "12345"📁 Group
val words = listOf("apple", "banana", "apricot", "blueberry", "cherry")
// groupBy
val byFirstLetter = words.groupBy { it.first() }
// {a=[apple, apricot], b=[banana, blueberry], c=[cherry]}
// partition
val (short, long) = words.partition { it.length <= 5 }
// short=[apple], long=[banana, apricot, blueberry, cherry]
// chunked
val numbers = (1..10).toList()
val chunks = numbers.chunked(3) // [[1,2,3], [4,5,6], [7,8,9], [10]]
// windowed
val windowed = numbers.windowed(3) // [[1,2,3], [2,3,4], [3,4,5], ...]
val sliding = numbers.windowed(3, step = 2) // [[1,2,3], [3,4,5], [5,6,7], ...]⚡ Sequence (Lazy Evaluation)
// Eager - xử lý toàn bộ list ở mỗi bước
val eagerResult = (1..1000000)
.map { it * 2 } // Tạo list mới với 1M items
.filter { it > 10 } // Tạo list mới nữa
.take(5) // Chỉ lấy 5 items
.toList()
// Lazy - chỉ xử lý khi cần
val lazyResult = (1..1000000)
.asSequence()
.map { it * 2 }
.filter { it > 10 }
.take(5)
.toList() // Chỉ xử lý 8 items thực tế!Khi nào dùng Sequence?
- Collection lớn (> 10,000 items)
- Có nhiều operations chain
- Không cần tất cả kết quả
🛠️ Thực hành
data class Transaction(val category: String, val amount: Double)
fun main() {
val transactions = listOf(
Transaction("Food", 50.0),
Transaction("Transport", 30.0),
Transaction("Food", 25.0),
Transaction("Entertainment", 100.0),
Transaction("Food", 40.0)
)
// TODO: Tính tổng chi tiêu theo category
// TODO: Tìm category chi tiêu nhiều nhất
}Lời giải:
fun main() {
val transactions = listOf(
Transaction("Food", 50.0),
Transaction("Transport", 30.0),
Transaction("Food", 25.0),
Transaction("Entertainment", 100.0),
Transaction("Food", 40.0)
)
val byCategory = transactions
.groupBy { it.category }
.mapValues { (_, txns) -> txns.sumOf { it.amount } }
println(byCategory) // {Food=115.0, Transport=30.0, Entertainment=100.0}
val topCategory = byCategory.maxByOrNull { it.value }
println("Top: ${topCategory?.key} = ${topCategory?.value}")
// Top: Food = 115.0
}✅ Checklist
- Sử dụng
map,filter,reduce,fold - Sử dụng
groupBy,partition,chunked - Biết khi nào dùng Sequence cho lazy evaluation
- Chain nhiều operations một cách hiệu quả
Tiếp theo: Class và Object
Last updated on