Building immutable collection dynamically in Kotlin
When and Why to Use Kotlin Collection Builders If there's a requirement to dynamically construct a collection based on certain conditions, two main approaches are available in Kotlin: Using a mutable collection directly Employing a collection builder function (e.g., buildSet, buildList, buildMap) The collection builder approach still uses a mutable collection internally, but the benefit lies in its encapsulation. This leads to cleaner and more concise code, and the final result is an immutable collection. This post is short and clear although I have met so much mutable collection in projects that is nice to remain it. Mutable way It works but collction must be muttable and code is less fluent. fun mapToWorkTypes(externalTypes: List): Set { val workTypes: MutableSet = mutableSetOf() if (externalTypes.contains("#001")) workTypes.add(EMPLOYEE) if (externalTypes.contains("#002")) workTypes.add(CONTRACTOR) if (externalTypes.contains("#003")) workTypes.add(SEASONAL) if (externalTypes.contains("#004")) workTypes.add(INTERN) if (externalTypes.contains("#005")) workTypes.add(CONTRACTOR) if (workTypes.isEmpty()) workTypes.add(EMPLOYEE) return workTypes.toSet() } Immutable way The code below uses collection builder. Check documentations of collection builders buildSet, buildList, buildMap. fun mapToWorkTypes(externalTypes: List) = buildSet { if (externalTypes.contains("#001")) add(EMPLOYEE) if (externalTypes.contains("#002")) add(CONTRACTOR) if (externalTypes.contains("#003")) add(SEASONAL) if (externalTypes.contains("#004")) add(INTERN) if (externalTypes.contains("#005")) add(CONTRACTOR) ifEmpty { add(EMPLOYEE) } } Conclusion Using a mutable collection directly requires more boilerplate and an explicit conversion to an immutable form via .toSet(). It also increases the risk of logic errors, such as accidentally checking or modifying the wrong collection (workTypes vs. externalTypes). In contrast, collection builders provide a cleaner and more concise alternative: Less boilerplate Clearer logic Automatically return immutable collections Encourage encapsulated and expressive code Whenever possible, prefer collection builders for constructing collections based on dynamic conditions.

When and Why to Use Kotlin Collection Builders
If there's a requirement to dynamically construct a collection based on certain conditions, two main approaches are available in Kotlin:
- Using a mutable collection directly
- Employing a collection builder function (e.g., buildSet, buildList, buildMap)
The collection builder approach still uses a mutable collection internally, but the benefit lies in its encapsulation. This leads to cleaner and more concise code, and the final result is an immutable collection.
This post is short and clear although I have met so much mutable collection in projects that is nice to remain it.
Mutable way
It works but collction must be muttable and code is less fluent.
fun mapToWorkTypes(externalTypes: List<String>): Set<WorkType> {
val workTypes: MutableSet<WorkType> = mutableSetOf()
if (externalTypes.contains("#001")) workTypes.add(EMPLOYEE)
if (externalTypes.contains("#002")) workTypes.add(CONTRACTOR)
if (externalTypes.contains("#003")) workTypes.add(SEASONAL)
if (externalTypes.contains("#004")) workTypes.add(INTERN)
if (externalTypes.contains("#005")) workTypes.add(CONTRACTOR)
if (workTypes.isEmpty()) workTypes.add(EMPLOYEE)
return workTypes.toSet()
}
Immutable way
The code below uses collection builder. Check documentations of collection builders buildSet, buildList, buildMap.
fun mapToWorkTypes(externalTypes: List<String>) =
buildSet {
if (externalTypes.contains("#001")) add(EMPLOYEE)
if (externalTypes.contains("#002")) add(CONTRACTOR)
if (externalTypes.contains("#003")) add(SEASONAL)
if (externalTypes.contains("#004")) add(INTERN)
if (externalTypes.contains("#005")) add(CONTRACTOR)
ifEmpty { add(EMPLOYEE) }
}
Conclusion
Using a mutable collection directly requires more boilerplate and an explicit conversion to an immutable form via .toSet(). It also increases the risk of logic errors, such as accidentally checking or modifying the wrong collection (workTypes vs. externalTypes).
In contrast, collection builders provide a cleaner and more concise alternative:
- Less boilerplate
- Clearer logic
- Automatically return immutable collections
- Encourage encapsulated and expressive code
Whenever possible, prefer collection builders for constructing collections based on dynamic conditions.