skip to content

What does toList() return on a Pair and a Triple, and what is its element type?

level: middleimportance: should knowfreq 45%

answer

  1. Pair.toList() → [first, second]
  2. Triple.toList() → [first, second, third]
  3. Only clean type when all positions share a type
  4. Mixed types collapse to List<Any>
  5. Order preserved; use for homogeneous tuples

basics

~10 s

Calling toList() on a Pair gives a list of its two values; on a Triple, a list of its three values. The order matches first, second, (third).

solid answer

~30 s

The stdlib provides `Pair<A, B>.toList(): List<A>` only when both type parameters are the same, and `Triple<A, B, C>.toList(): List<A>` when all three match — the returned element type is the common type, otherwise the compiler infers the closest common supertype (often Any/Any?). `pair.toList()` yields `listOf(first, second)` and `triple.toList()` yields `listOf(first, second, third)`, preserving order. When types differ, you get `List<Any>` (or `List<Any?>` with nullables), losing static type information. Use it when you genuinely want to iterate homogeneous tuple elements; otherwise keep first/second/third for type safety.

code

kotlin · 3 lines
kotlin
val coords = (10 to 20).toList()       // List<Int> [10, 20]
val rgb = Triple(255, 128, 0).toList() // List<Int> [255,128,0]
val mixed = ("a" to 1).toList()        // List<Any> — types lost

go deeper

for a junior

Knows toList() returns the elements as an ordered list.

for a middle

States element ordering and that homogeneous tuples give a precisely-typed List.

for a senior

Explains the least-common-supertype inference and the type-information loss for heterogeneous tuples.

for a principal

Weighs toList() vs destructuring vs named types for API clarity and warns against erasing types via toList() in shared code.

## toList() on tuples The Kotlin standard library defines extension functions: ```kotlin public fun <T> Pair<T, T>.toList(): List<T> = listOf(first, second) public fun <T> Triple<T, T, T>.toList(): List<T> = listOf(first, second, third) ``` They convert a tuple into an ordered `List`, preserving positional order: `first`, then `second`, then (for Triple) `third`. ```kotlin val coords = (10 to 20).toList() // List<Int> = [10, 20] val rgb = Triple(255, 128, 0).toList() // List<Int> = [255, 128, 0] ``` ## Element type when types differ The signatures are written for a single type parameter `T` shared by all positions. When the actual types differ, the compiler still resolves `T` to their **least common supertype**: ```kotlin val mixed = ("a" to 1).toList() // List<Comparable<*>> / Any — common supertype ``` In practice mixed tuples collapse to `List<Any>` (or `List<Any?>` if any element is nullable), so you **lose the distinct static types** and would need casts to use elements specifically. ## When to use it - Good: the tuple is **homogeneous** (e.g., `Pair<Int, Int>` coordinates) and you want list operations like `forEach`, `sum`, `max`. - Avoid: heterogeneous tuples where you'd rather read `.first`/`.second` with their precise types. ## Contrast with destructuring `toList()` gives you a single `List` (good for iteration); destructuring gives you separately typed locals (good for distinct types). They solve different needs: ```kotlin val (x, y) = 10 to 20 // two typed Ints val list = (10 to 20).toList() // one List<Int> ```

  • What is the element type of ("a" to 1).toList()?
    The common supertype of String and Int — effectively List<Any>; you lose the distinct types.
  • Does toList() preserve order?
    Yes — first, then second, then third for Triple.

saying these in an interview costs you the question

  • Claiming toList() keeps each element's distinct static type for mixed tuples
  • Thinking the order is unspecified or alphabetical
  • Believing toList() exists for arbitrary-arity tuples (there are only Pair and Triple)
  • Confusing toList() with destructuring's separately-typed locals

context