In Kotlin, how do you check whether a value lies inside a range, and what does the `in` operator do under the hood for a range like `1..10`?
answer
- `a in b` == `b.contains(a)`
- `..` ranges are inclusive at BOTH ends
- membership is O(1) comparison, not iteration
- `!in` negates
- great inside `when` branches
basics
~10 sUse the in keyword: x in 1..10 is true when x is between 1 and 10, both ends included. !in checks the opposite. It calls the range's contains method.
solid answer
~40 sWrite `value in range` to test membership; it returns a `Boolean`. For `1..10` (an `IntRange`, both endpoints inclusive), `x in 1..10` compiles to `(1..10).contains(x)`. The `in` operator is sugar for the `contains` operator function, and `!in` negates it. Because `IntRange` overrides `contains` with a simple `first <= value && value <= last` comparison (no iteration), the check is O(1). You can use `in` in `if`, `while`, and especially `when` branches: `when (x) { in 1..10 -> ... }`. The same syntax works for `CharRange` and `LongRange`. Mixing types matters: `1.5 in 1..10` won't compile because `1..10` is an `IntRange`; you'd use `1.0..10.0` (a `ClosedFloatingPointRange`) instead.
code
kotlin · 9 linesval temp = 23
val comfortable = temp in 18..26 // true, == (18..26).contains(23)
val label = when (temp) {
in Int.MIN_VALUE..0 -> "freezing"
in 1..17 -> "cold"
in 18..26 -> "comfortable"
else -> "hot"
}
println(label) // comfortablego deeper
Knows x in 1..10, that both ends are inclusive, and that !in negates.
Explains in desugars to contains and that numeric membership is an O(1) comparison, not a loop.
Connects in to the operator-overloading convention and notes the type-matching rule (Int vs Double ranges).
Discusses when in semantics differ across range types and why contains overrides matter for performance and API design.
## What `in` means for ranges A **range** in Kotlin is an object describing a closed interval. `1..10` creates an `IntRange` whose endpoints are **both inclusive** (1 and 10 are members). The `in` operator answers the yes/no question "is this value a member?" and returns a `Boolean`. ## `in` is operator sugar for `contains` Kotlin translates `a in b` into `b.contains(a)` — the receiver is the range on the **right**, the candidate value is on the **left**. `!in` translates to `!b.contains(a)`. This is the **operator-overloading convention**: any type that declares an `operator fun contains(...)` supports `in`. ```kotlin val r = 1..10 println(5 in r) // true -> r.contains(5) println(0 in r) // false println(10 in r) // true (last endpoint is inclusive) println(7 !in r) // false -> !r.contains(7) ``` ## It's a comparison, not a loop For numeric ranges, `contains` does **not** iterate. `IntRange.contains` is essentially `first <= value && value <= last`, so the test is **O(1)** regardless of how big the range is — `1_000_000 in 1..1_000_000_000` is instant. ## Works anywhere a Boolean is expected ```kotlin if (score in 0..100) { /* valid */ } while (i in 1..n) { /* ... */ } val grade = when (score) { in 90..100 -> "A" in 80..89 -> "B" else -> "F" } ``` The `when (subject)` form is a very common place to use `in` because each branch reads as a clean membership test. ## Type must match the range `1..10` is an `IntRange`. Putting a `Double` on the left (`1.5 in 1..10`) fails to compile because there is no `contains(Double)` on `IntRange`. For floating-point intervals use `1.0..10.0`, which is a `ClosedFloatingPointRange<Double>`.
- What does `x !in 1..10` compile to?`!(1..10).contains(x)` — the same `contains` call, negated.
- Is `10 in 1..10` true or false?True. The `..` operator produces a range that is inclusive on both ends, so the last endpoint is a member.
in is like asking a bouncer 'is my number on the guest list between 1 and 10?' — one glance, not reading every name.
saying these in an interview costs you the question
- Saying `in` iterates the whole range to find the value (it's a comparison for numeric ranges).
- Claiming the upper bound is exclusive for `..` (that's `until`, a sibling topic).
- Writing `1..10 in x` with operands reversed.
- Thinking `1.5 in 1..10` compiles.