⚙️ Collections Operations
🎯 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
Phần tiêu đề “💡 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
Phần tiêu đề “🔄 Transform”val numbers = listOf(1, 2, 3, 4, 5)
// mapval doubled = numbers.map { it * 2 } // [2, 4, 6, 8, 10]
// flatMapval nested = listOf(listOf(1, 2), listOf(3, 4))val flattened = nested.flatMap { it } // [1, 2, 3, 4]
// zipval 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]
// associateval users = listOf("Alice", "Bob")val userMap = users.associateWith { it.length } // {Alice=5, Bob=3}🔍 Filter
Phần tiêu đề “🔍 Filter”val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// filter / filterNotval even = numbers.filter { it % 2 == 0 } // [2, 4, 6, 8, 10]val odd = numbers.filterNot { it % 2 == 0 } // [1, 3, 5, 7, 9]
// take / dropval 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 / dropWhileval takeSmall = numbers.takeWhile { it < 5 } // [1, 2, 3, 4]val dropSmall = numbers.dropWhile { it < 5 } // [5, 6, 7, 8, 9, 10]
// distinctval withDups = listOf(1, 2, 2, 3, 3, 3)val unique = withDups.distinct() // [1, 2, 3]📊 Aggregate
Phần tiêu đề “📊 Aggregate”val numbers = listOf(1, 2, 3, 4, 5)
println(numbers.sum()) // 15println(numbers.average()) // 3.0println(numbers.max()) // 5println(numbers.min()) // 1println(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 } // 120val concat = numbers.fold("") { acc, n -> "$acc$n" } // "12345"📁 Group
Phần tiêu đề “📁 Group”val words = listOf("apple", "banana", "apricot", "blueberry", "cherry")
// groupByval byFirstLetter = words.groupBy { it.first() }// {a=[apple, apricot], b=[banana, blueberry], c=[cherry]}
// partitionval (short, long) = words.partition { it.length <= 5 }// short=[apple], long=[banana, apricot, blueberry, cherry]
// chunkedval numbers = (1..10).toList()val chunks = numbers.chunked(3) // [[1,2,3], [4,5,6], [7,8,9], [10]]
// windowedval 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)
Phần tiêu đề “⚡ Sequence (Lazy Evaluation)”// Eager - xử lý toàn bộ list ở mỗi bướcval 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ầnval 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?
Phần tiêu đề “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
Phần tiêu đề “🛠️ 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
Phần tiêu đề “✅ 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