List, Set, Map, and operator directory
Start by choosing the correct shape:
| Shape | Meaning | Example |
|---|---|---|
List<T> | Ordered; duplicates allowed; indexed | Search results |
Set<T> | Unique elements by equality | Selected IDs |
Map<K, V> | Unique keys associated with values | User by ID |
See the behavioral differences
fun main() {
val names: List<String> = listOf("Ada", "Ada", "Grace")
val uniqueNames: Set<String> = names.toSet()
val ages: Map<String, Int> = mapOf("Ada" to 36, "Grace" to 85)
println(names) // [Ada, Ada, Grace]
println(uniqueNames) // [Ada, Grace]
println(ages["Ada"]) // 36
println(ages["Missing"]) // null
}
A Set is not “a faster List.” It represents a different domain rule: duplicates have no meaning. A Map lookup is nullable because the requested key may not exist.
Transformation pipeline
fun main() {
val numbers = listOf(1, 2, 3, 4)
val result = numbers
.filter { number -> number % 2 == 0 }
.map { number -> number * number }
println(numbers) // [1, 2, 3, 4]
println(result) // [4, 16]
}
filter creates the matching result; map creates one transformed value per input. Neither operation mutates numbers.
Complete operator directory
Use this as a discovery index, then open the linked lesson for behavior, edge cases, output, and runnable examples.
| Family | Important operations | Detailed lesson |
|---|---|---|
| Access | first, firstOrNull, last, lastOrNull, single, singleOrNull, getOrNull, elementAtOrNull, elementAtOrElse, random, randomOrNull | Access and search |
| Search | find, indexOf, indexOfFirst, indexOfLast | Access and search |
| Filter | filter, filterNot, filterIndexed, filterNotNull, filterIsInstance | Filtering and types |
| Transform | map, mapIndexed, mapNotNull, flatMap, flatten | Advanced operations |
| Check | any, all, none, contains, containsAll | Advanced operations |
| Slice | take, drop, takeLast, dropLast, takeWhile, dropWhile, takeLastWhile, dropLastWhile | Advanced operations |
| List-specific | slice, subList, binarySearch, zipWithNext, indexed mutations, fill, asReversed | List operations |
| Map-specific | getValue, getOrElse, getOrPut, mapKeys, mapValues, filterKeys, filterValues | Map operations |
| Set algebra | union, intersect, subtract | Set algebra |
| Sort | sorted, sortedDescending, sortedBy, sortedWith, sortBy, reversed, shuffled | Sorting |
| Aggregate | sum, sumOf, average, count, minByOrNull, maxByOrNull, fold, reduce, runningFold, foldRight | Basic / advanced |
| Group | groupBy, groupingBy, eachCount | Grouping |
| Map creation | associate, associateBy, associateWith | Association |
| Unique | distinct, distinctBy, toSet | Advanced operations |
| Combine | zip, unzip, plus, minus | Advanced operations |
| Split | partition, chunked, windowed | Advanced operations |
| Mutation | add, addAll, remove, removeAt, clear, retainAll | Mutation and copying |
| Destinations/builders | filterTo, mapTo, associateTo, groupByTo, buildList, buildSet, buildMap | Destination/build operations |
Predict the output
fun main() {
val values = listOf(1, 2, 2, 3)
val changed = values
.toSet()
.map { it * 10 }
println(values)
println(changed)
}
Reveal
The original remains [1, 2, 2, 3]. The Set removes the duplicate, and map returns [10, 20, 30] for the current insertion-preserving implementation. Do not treat incidental ordering from an arbitrary Set implementation as a universal business guarantee.
Choose List, Set, or Map from the domain's cardinality and ordering rules. Then choose operators by behavior: throwing versus nullable, first match versus all matches, new result versus mutation, one value per key versus many, eager versus lazy, and silent duplicate replacement versus validation.