# Intermediate collection avoidance

DevFeed: [Intermediate collection avoidance](<https://devfeed.tech/articles/intermediate-collection-avoidance-20942.md>)

Original publisher: [Read original article](<https://jakewharton.com/intermediate-collection-avoidance/>)

Published: 2024-02-07T00:00:00Z

Content type: article

Language: en

Sources: [Jake Wharton](<https://devfeed.tech/sources/jake-wharton.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [IntelliJ IDEA](<https://devfeed.tech/topics/intellij-idea.md>), [Code](<https://devfeed.tech/topics/code.md>), [Compose](<https://devfeed.tech/topics/compose.md>)

Tags: [benchmarks](<https://devfeed.tech/tags/benchmarks.md>), [compose](<https://devfeed.tech/tags/compose.md>), [intellij](<https://devfeed.tech/tags/intellij.md>), [java](<https://devfeed.tech/tags/java.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [memory](<https://devfeed.tech/tags/memory.md>), [performance](<https://devfeed.tech/tags/performance.md>), [refactor](<https://devfeed.tech/tags/refactor.md>)

## AI overview

This article explains how to avoid intermediate iterators and collections in Kotlin collection operations. It presents fused string joining, array initialization, and pre-sized list initialization as shorter, faster approaches that can reduce allocations, while noting that indexed access is important for performance and that these techniques are best suited to controlled internal usage.

## Source excerpt

Given a list of users, extract their names and join them into a comma-separated list. Kotlin's extension functions on collections make this trivial. users.map { it.name }.joinToString() Writing this in IntelliJ IDEA produces a "weak warning" offering advice. Call chain on collection type may be simplified An intention action will refactor the code for you to a more efficient form. users.joinToString() { it.name } Mapping the user to their name now occurs during construction of the joined string rather than as a discrete operation. The additional iterator and intermediate collection produced by the map is eliminated. This code is both shorter and faster, and the IDE helps you discover this superior form. Two similar fused operations that I like but which don't benefit from IDE advice are array and pre-sized list initialization with a lambda. If we wanted to create an array of our user's names, instead of doing users.map { it.name }.toTypedArray() we can use Array(users.size) { users[it].name } This again trades the intermediate iterator and collection within map for an indexed loop. Primitive array versions are also available. IntArray(users.size) { users[it].age } Arrays are not used too often. Mostly for memory-sensitive or performance-sensitive code, or when calling out to a Java API. Thankfully this lambda-accepting initializer is also available for pre-sized lists. MutableList(users.size) { users[it].name } Use this to initialize element default values, compute elements based on the index, or derive data from another source. In the case of deriving data, the source needs to support random access in order to actually result in a more efficient computation.1 If you use a list backed by an alternate structure (linked, persistent, etc.) performance will be abysmal. This technique works best for internal library usage and should not be used when you don't control the original list. Benchmark Score Error Units --------------------------------------------- ---------- -