Chapter 17: Collections – Operations

Collections – Operations β€” this is the chapter where your Kotlin collections come to life and start doing real magic! β˜•πŸš€

In the last chapter, we learned how to create collections (read-only vs mutable, listOf, setOf, etc.). Now, we’ll focus on operations β€” the functions that let you transform, filter, group, and aggregate data in clean, concise ways. These are the tools you’ll use every day in real Kotlin projects (Android apps, backend services, data processing).

We’ll go super slowly, like we’re sitting together in a quiet Bandra cafΓ© β€” I’ll explain each operation with real-life analogies, complete runnable examples, step-by-step breakdowns, tables, common mistakes with fixes, and fun facts so everything sticks perfectly.

All examples use Kotlin 1.9+ (2026 standard) β€” copy-paste them into IntelliJ and run!

Let’s dive in!

1. Transformation Operations – Filter, Map, FlatMap

These operations create new collections from existing ones β€” they are immutable (don’t change the original).

A. filter – Keep Only What Matches

filter takes a predicate (condition lambda) and returns a new collection with elements that match it.

Real-life analogy: You have a basket of fruits β€” filter is like picking only the apples, leaving the basket unchanged.

Example:

Kotlin

Step-by-step:

  1. For each element, apply the lambda β†’ if true, keep it.
  2. Returns a new List (same type as original if possible).

B. map – Transform Each Element

map takes a transformation lambda and returns a new collection with transformed elements.

Real-life analogy: You have a list of apples β€” map is like turning each apple into apple juice.

Example:

Kotlin

C. flatMap – Map + Flatten Nested Collections

flatMap is like map, but if your transformation returns a collection, it flattens them into one big collection.

Real-life analogy: You have boxes of fruits (map opens each box into a list) β€” flatMap pours all fruits into one big basket.

Example:

Kotlin

2. Association & Grouping Operations – associate, groupBy

These create maps from collections.

A. associate – Create Map from Key-Value Pairs

associate takes a lambda that returns a Pair (key to value) β†’ builds a Map.

Example:

Kotlin

B. groupBy – Group Elements into Map<List>

groupBy takes a key selector lambda β†’ returns Map<Key, List<T>>

Example:

Kotlin

3. Pairing & Splitting – zip, partition, chunked, windowed

A. zip – Pair Elements from Two Collections

zip combines two collections into List<Pair> or transforms with lambda.

Example:

Kotlin

B. partition – Split into Two Lists Based on Condition

partition returns Pair<List<T>, List<T>> β€” matching and non-matching.

Example:

Kotlin

C. chunked – Split into Chunks of Size N

chunked returns List<List<T>> of chunks.

Example:

Kotlin

D. windowed – Sliding Windows of Size N

windowed returns List<List<T>> of overlapping windows.

Example:

Kotlin

4. Folding & Reducing – fold, reduce, sumOf, etc.

These aggregate collections into a single value.

A. fold – Aggregate with Initial Value

fold takes an initial accumulator + lambda β†’ applies to each element.

Example:

Kotlin

B. reduce – Aggregate Without Initial Value

reduce is like fold but uses first element as initial accumulator.

Example:

Kotlin

C. sumOf – Sum with Projection

sumOf sums a projection (transformed values).

Example:

Kotlin

Other aggregates: count(), maxOf { }, minOf { }, average()

5. Sequences (asSequence()) – Lazy Collections

Sequences are like collections but lazy β€” they compute only when needed.

Use asSequence() to convert a collection to a sequence.

Why use sequences?

  • For large data β€” avoid creating intermediate collections
  • Better performance for chained operations
  • Infinite sequences possible

Example:

Kotlin

Output:

text

See? Lazy version only processed until it found the first even number!

Infinite sequence example:

Kotlin

Quick Recap Table (Your Cheat Sheet)

Operation Purpose Returns Example
filter Keep matching elements New collection .filter { it > 0 }
map Transform each New collection .map { it * 2 }
flatMap Transform + flatten New flattened collection .flatMap { it.split(” “) }
associate Build Map from pairs Map .associate { it to it.length }
groupBy Group into Map<List> Map<Key, List<T>> .groupBy { it % 2 }
zip Pair with another collection List<Pair> or transformed .zip(other) { a, b -> a + b }
partition Split into two lists Pair<List<T>, List<T>> .partition { it > 0 }
chunked Split into chunks List<List<T>> .chunked(3)
windowed Sliding windows List<List<T>> .windowed(3)
fold Aggregate with initial Single value .fold(0) { acc, num -> acc + num }
reduce Aggregate without initial Single value .reduce { acc, num -> acc + num }
sumOf Sum of projections Long/Double .sumOf { it.length }
asSequence Convert to lazy sequence Sequence .asSequence().filter{…}.map{…}.toList()

Common Newbie Mistakes & Fixes

Mistake Problem Fix
Using map instead of flatMap Nested lists instead of flat Use flatMap when transform returns collection
Forgetting toList() after operations Stream/Sequence – no output Chain .toList() or use terminal like .forEach
Using reduce on empty collection IllegalArgumentException Check empty or use fold with initial
Not using asSequence on large data OutOfMemoryError or slow Add .asSequence() for lazy processing
Confusing chunked and windowed Wrong splitting chunked = non-overlap, windowed = sliding

Homework for You (Let’s Make It Fun!)

  1. Basic From listOf(1,2,3,4,5,6,7,8,9,10) β†’ filter odds β†’ map to squares β†’ print list.
  2. Medium From list of strings [“apple:5”, “banana:3”, “cherry:8”] β†’ use associate to make Map<String, Int> (fruit to quantity).
  3. Advanced From list of numbers 1 to 20 β†’ use partition to split even/odd β†’ print sums using sumOf.
  4. Fun From list of sentences β†’ use flatMap to get all words β†’ groupBy first letter.
  5. Challenge Create an infinite sequence of Fibonacci numbers β†’ use take(10) β†’ print using fold to build a string.

You’ve just mastered Kotlin’s collection operations β€” now you can process data like a pro!

Ready for Chapter 18: Sequences & Lazy Evaluation? Or want me to explain any operation again with more examples or debug your code? Just tell me β€” I’m right here with another cup of cutting chai! β˜•πŸš€<|control12|>Hey Webliance! Welcome to Chapter 17: Collections – Operations β€” this is the chapter where your Kotlin collections come to life and start doing real magic! β˜•πŸš€

In the last chapter, we learned how to create collections (read-only vs mutable, listOf, setOf, etc.). Now, we’ll focus on operations β€” the functions that let you transform, filter, group, and aggregate data in clean, concise ways. These are the tools you’ll use every day in real Kotlin projects (Android apps, backend services, data processing).

We’ll go super slowly, like we’re sitting together in a quiet Bandra cafΓ© β€” I’ll explain each operation with real-life analogies, complete runnable examples, step-by-step breakdowns, tables, common mistakes with fixes, and fun facts so everything sticks perfectly.

All examples use Kotlin 1.9+ (2026 standard) β€” copy-paste them into IntelliJ and run!

Let’s dive in!

1. Transformation Operations – Filter, Map, FlatMap

These operations create new collections from existing ones β€” they are immutable (don’t change the original).

A. filter – Keep Only What Matches

filter takes a predicate (condition lambda) and returns a new collection with elements that match it.

Real-life analogy: You have a basket of fruits β€” filter is like picking only the apples, leaving the basket unchanged.

Example:

Kotlin

Step-by-step:

  1. For each element, apply the lambda β†’ if true, keep it.
  2. Returns a new List (same type as original if possible).

Fun fact: filter is lazy β€” it doesn’t create the new list until you use it (e.g., print or collect). This is why it’s efficient!

B. map – Transform Each Element

map takes a transformation lambda and returns a new collection with transformed elements.

Real-life analogy: You have a list of apples β€” map is like turning each apple into apple juice.

Example:

Kotlin

Step-by-step:

  1. For each element, apply the lambda β†’ get new value.
  2. Collects all new values into a new List.

Common mistake: Forgetting that map returns a new collection β€” original remains unchanged.

C. flatMap – Map + Flatten Nested Collections

flatMap is like map, but if your transformation returns a collection, it flattens them into one big collection.

Real-life analogy: You have boxes of fruits (map opens each box into a list) β€” flatMap pours all fruits into one big basket.

Example:

Kotlin

Step-by-step:

  1. For each element, apply lambda β†’ get a collection.
  2. Flatten all into one big collection.

Fun fact: flatMap is perfect for processing JSON-like nested data.

2. Association & Grouping Operations – associate, groupBy

These create maps from collections.

A. associate – Create Map from Key-Value Pairs

associate takes a lambda that returns a Pair (key to value) β†’ builds a Map.

Example:

Kotlin

Step-by-step:

  1. Lambda returns Pair (key to value).
  2. If duplicate keys β†’ last one wins.

B. groupBy – Group Elements into Map<List>

groupBy takes a key selector lambda β†’ returns Map<Key, List<T>>

Example:

Kotlin

Step-by-step:

  1. Lambda returns key for each element.
  2. Elements with same key go into the same List.

3. Pairing & Splitting Operations – zip, partition, chunked, windowed

A. zip – Pair Elements from Two Collections

zip combines two collections into List<Pair> or transforms with lambda.

Example:

Kotlin

Step-by-step:

  1. Pairs corresponding elements (shorter list determines size).
  2. If lambda β†’ apply to each pair.

B. partition – Split into Two Lists Based on Condition

partition returns Pair<List<T>, List<T>> β€” matching and non-matching.

Example:

Kotlin

Step-by-step:

  1. Lambda decides which list each element goes to.
  2. Use destructuring to get the pair.

C. chunked – Split into Chunks of Size N

chunked returns List<List<T>> of chunks.

Example:

Kotlin

Step-by-step:

  1. Splits into non-overlapping chunks of size N.
  2. Last chunk may be smaller.

D. windowed – Sliding Windows of Size N

windowed returns List<List<T>> of overlapping windows.

Example:

Kotlin

Step-by-step:

  1. Creates sliding windows of size N, step S.
  2. partialWindows = true β†’ includes smaller end windows.

4. Folding & Reducing Operations – fold, reduce, sumOf, etc.

These aggregate collections into a single value.

A. fold – Aggregate with Initial Value

fold takes an initial accumulator + lambda β†’ applies to each element.

Example:

Kotlin

Step-by-step:

  1. Start with initial value.
  2. For each element: acc = lambda(acc, element)

B. reduce – Aggregate Without Initial Value

reduce is like fold but uses first element as initial accumulator.

Example:

Kotlin

Step-by-step:

  1. Initial acc = first element
  2. Then apply lambda to rest

C. sumOf – Sum with Projection

sumOf sums a projection (transformed values).

Example:

Kotlin

Other aggregates:

  • count() β†’ total elements
  • maxOf { } / minOf { } β†’ max/min by projection
  • average() β†’ average (Double)

5. Sequences (asSequence()) – Lazy Processing for Efficiency

Sequences are like collections but lazy β€” they compute on-demand, avoiding intermediate collections.

Convert with .asSequence()

Real-life analogy: Collections = baking all cookies at once (eager). Sequences = baking one cookie when someone asks (lazy) β€” saves time if they only eat a few.

Example – Eager vs Lazy

Kotlin

Output:

text

Step-by-step: Lazy version stops after finding first even number (2) β†’ much more efficient for large data!

Infinite sequence:

Kotlin

When to use sequences?

  • Large collections (>10k elements)
  • Chained operations (filter + map + etc.)
  • Infinite data (generators, sequences)

Quick Recap Table (Your Cheat Sheet)

Operation Purpose Returns Example
filter Keep matching elements New collection .filter { it > 0 }
map Transform each New collection .map { it * 2 }
flatMap Transform + flatten New flattened collection .flatMap { it.split(” “) }
associate Build Map from pairs Map .associate { it to it.length }
groupBy Group into Map<List> Map<Key, List<T>> .groupBy { it % 2 }
zip Pair with another collection List<Pair> or transformed .zip(other) { a, b -> a + b }
partition Split into two lists Pair<List<T>, List<T>> .partition { it > 0 }
chunked Split into chunks List<List<T>> .chunked(3)
windowed Sliding windows List<List<T>> .windowed(3)
fold Aggregate with initial Single value .fold(0) { acc, num -> acc + num }
reduce Aggregate without initial Single value .reduce { acc, num -> acc + num }
sumOf Sum of projections Long/Double .sumOf { it.length }
asSequence Convert to lazy sequence Sequence .asSequence().filter{…}.map{…}.toList()

Common Newbie Mistakes & Fixes

Mistake Problem Fix
Using map instead of flatMap Nested lists instead of flat Use flatMap when transform returns collection
Forgetting toList() after operations Stream/Sequence – no output Chain .toList() or use terminal like .forEach
Using reduce on empty collection IllegalArgumentException Check empty or use fold with initial
Not using asSequence on large data OutOfMemoryError or slow Add .asSequence() for lazy processing
Confusing chunked and windowed Wrong splitting chunked = non-overlap, windowed = sliding

Homework for You (Let’s Make It Fun!)

  1. Basic From listOf(1,2,3,4,5,6,7,8,9,10) β†’ filter odds β†’ map to squares β†’ print list.
  2. Medium From list of strings [“apple:5”, “banana:3”, “cherry:8”] β†’ use associate to make Map<String, Int> (fruit to quantity).
  3. Advanced From list of numbers 1 to 20 β†’ use partition to split even/odd β†’ print sums using sumOf.
  4. Fun From list of sentences β†’ use flatMap to get all words β†’ groupBy first letter.
  5. Challenge Create an infinite sequence of Fibonacci numbers β†’ use take(10) β†’ print using fold to build a string.

You’ve just mastered Kotlin’s collection operations β€” now you can process data like a pro!

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *