skip to content

for/while & Ranges

Kotlin's for loop iterates anything exposing iterator(), typically over ranges built with .., until, downTo, and step. The thing to internalize is that there is no C-style three-part for, so index-based loops become ranges, indices, or withIndex().

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

6

Kotlin has no C-style three-part for loop (for (int i=0; i<n; i++)). How do you write the equivalent loops in Kotlin, and what does the for loop actually require to iterate?

level: juniorimportance: must knowfreq 70%

answer

  1. for = foreach, needs iterator()
  2. 0 until n replaces i<n
  3. 1..n inclusive, until exclusive
  4. downTo / step for direction & stride
  5. irregular update -> while

basics

~10 s

Kotlin's for loop walks over a sequence, not a counter. To count, you loop over a range like 0 until n. For anything else, for works on anything you can iterate, like a list.

solid answer

~40 s

Kotlin deliberately drops the C-style for(init; cond; step) form. Instead, for (x in something) iterates over anything that provides an iterator() function (a member or extension). To count, you build a range and iterate it: for (i in 0 until n) replaces the classic i=0; i<n; i++. For other directions/strides use downTo and step. The equivalent of a manual counter loop is just for (i in 0 until list.size), but idiomatically you iterate the collection directly: for (item in list). When you need both the index and the value, use for ((index, value) in list.withIndex()). If you genuinely need arbitrary update logic, fall back to a while loop. The key idea: Kotlin for is a foreach over an Iterable/range, never a three-part counter.

code

kotlin · 11 lines
kotlin
// Java: for (int i = 0; i < n; i++)
for (i in 0 until n) print(i)

// Java: for (int i = n-1; i >= 0; i--)
for (i in n - 1 downTo 0) print(i)

// Idiomatic: iterate the collection itself
for (item in items) println(item)

// Custom iterable via extension iterator()
operator fun ClosedRange<MyDate>.iterator(): Iterator<MyDate> = TODO()

go deeper

for a junior

Knows for is foreach and uses 0 until n for index loops.

for a middle

Distinguishes until/../downTo/step correctly and reaches for while when stepping is irregular.

for a senior

Explains the iterator() operator contract and that any type providing it works in for, including extension iterators.

for a principal

Frames the design rationale (fewer off-by-one bugs, ranges as first-class objects) and the cost/zero-cost tradeoffs of range iteration.

## Why no C-style for In Java/C you write `for (int i = 0; i < n; i++)` — three parts: **init**, **condition**, **update**. Kotlin removed this form entirely to avoid off-by-one bugs and to make loops read as iteration over a sequence. ## What Kotlin's for requires The `for (x in expr)` loop works on any `expr` whose type provides an **`iterator()`** function returning something with `next()` and `hasNext()`. That function can be a **member** (collections, arrays, ranges, strings, maps) or even an **extension function** you declare yourself. So `for` is a *foreach*, not a counter. ## Counting with ranges To reproduce a counter you iterate a **range expression**: ```kotlin for (i in 0 until n) { /* i = 0,1,...,n-1 */ } // like i<n for (i in 1..n) { /* i = 1,2,...,n */ } // inclusive both ends for (i in n downTo 1){ /* counts down */ } for (i in 0 until n step 2) { /* stride of 2 */ } ``` - `1..10` — `rangeTo`, **inclusive** of both ends (1..10 = 1,2,...,10). - `0 until 10` — half-open, **excludes** the upper bound (0..9). Best match for index loops. - `10 downTo 1` — descending. - `step k` — changes the stride (must be positive even for downTo). ## Idiomatic iteration Usually you don't need indices at all: ```kotlin for (item in list) println(item) for (c in "hello") println(c) // String is iterable for ((k, v) in map) println("$k=$v") // destructuring map entries ``` ## When you really need arbitrary update If the update isn't a fixed stride (e.g. `i *= 2`), use a `while`: ```kotlin var i = 1 while (i < n) { i *= 2 } ``` ## Summary Kotlin `for` = foreach over anything with `iterator()`. Counters are expressed as ranges (`until`, `downTo`, `step`); irregular stepping uses `while`.

  • What's the difference between 0 until n and 0..n?
    0 until n is half-open and yields 0..n-1 (good for indices); 0..n is inclusive and yields 0..n, one extra element.
  • Can you make your own type usable in a for loop?
    Yes — declare an operator function iterator() (member or extension) returning an Iterator with next()/hasNext().

A C-style for is like manually turning an odometer; Kotlin's for is like walking down a pre-laid track — you describe the track (a range), not the steps.

saying these in an interview costs you the question

  • Claiming Kotlin has a three-part for loop
  • Using 1..n.size where 0 until size is meant (off-by-one)
  • Thinking for only works on lists/arrays, not custom types
  • Confusing until (exclusive) with .. (inclusive)

context

open as a page

Explain the range-building expressions in Kotlin: 1..10, until, downTo, and step. What does each produce and what are the gotchas (e.g. step with downTo, empty ranges)?

level: middleimportance: must knowfreq 65%

basics

~10 s

1..10 counts 1 to 10 including both ends. until stops one before the end. downTo counts backwards. step changes how big each jump is. Mixing them wrong can make an empty range.

open as a page

Compare while and do-while in Kotlin, and explain when you'd choose a while loop over a for/range loop. What's special about the scope of variables declared in a do-while condition?

level: middleimportance: should knowfreq 45%

basics

~10 s

while checks the condition before running the body, so it may run zero times. do-while runs the body once first, then checks. Use while when the number of steps isn't a simple count.

open as a page

You need both the index and the element while iterating a list. Show the idiomatic Kotlin way and explain what withIndex() returns and how it compares to indices.

level: middleimportance: should knowfreq 55%

basics

~10 s

Use withIndex() in the for loop. It gives you a pair of (position, value) for each item, so you can read both at once without manually tracking a counter.

open as a page

How does Kotlin's for loop decide that a type is iterable, and how would you make a custom type (or even a range of a custom type) usable in a for loop? What desugaring happens under the hood?

level: seniorimportance: should knowfreq 35%

basics

~20 s

A for loop works on anything that provides an iterator. You give your type an iterator() function (or add one as an extension), returning an object with hasNext() and next(). Then for just works on it.

open as a page

Are Kotlin range/for loops zero-overhead compared to handwritten index loops, and what allocations or boxing might occur? Discuss IntRange vs an IntProgression and the .indices iteration pattern.

level: seniorimportance: nice to knowfreq 25%

basics

~20 s

Plain integer for-loops like for (i in 0 until n) compile down to fast counter loops with no boxing. Costs can appear if you turn a range into an object, use very large Long ranges, or box values via generics.

open as a page