Kotlin in Keyword
last modified April 19, 2025
Kotlin's in
keyword is a versatile operator used for range checking
and iteration. It simplifies collection operations and range comparisons. This
tutorial explores the in
keyword in depth with practical examples.
Basic Definitions
The in
keyword in Kotlin serves two main purposes. First, it checks
if a value is within a range or collection. Second, it enables iteration over
collections or ranges. The operator is overloadable via the contains
function.
Range Checking with in
The simplest use of in
checks if a value falls within a specified
range. This works with numeric ranges, character ranges, and custom ranges.
package com.zetcode fun main() { val x = 5 if (x in 1..10) { println("$x is between 1 and 10") } val grade = 'B' if (grade in 'A'..'D') { println("$grade is a passing grade") } }
Here we check if a number is within 1-10 range and if a character is between A-D.
The in
operator makes these checks concise and readable. Both
conditions evaluate to true in these examples.
Collection Membership Check
The in
operator can check if an element exists in a collection. This
works with lists, sets, arrays, and other collection types.
package com.zetcode fun main() { val colors = listOf("red", "green", "blue") if ("green" in colors) { println("Green is in the list") } val numbers = setOf(1, 2, 3, 5, 8) println(4 in numbers) // Output: false }
We check if "green" exists in a list of colors and if 4 exists in a set of
numbers. The first check returns true while the second returns false. The
in
operator calls the contains
method internally.
Iteration with in
The in
keyword enables iteration over ranges and collections in
for
loops. This provides a clean syntax for looping operations.
package com.zetcode fun main() { for (i in 1..5) { print("$i ") // Output: 1 2 3 4 5 } println() val fruits = listOf("apple", "banana", "cherry") for (fruit in fruits) { print("$fruit ") // Output: apple banana cherry } }
The first loop iterates over a numeric range from 1 to 5. The second loop
iterates through a list of fruits. The in
keyword makes these loops
concise and easy to understand.
Custom in Operator
You can define custom behavior for the in
operator by implementing
the contains
function in your classes. This enables range-like
operations on custom types.
package com.zetcode class Week(val days: List<String>) { operator fun contains(day: String) = day in days } fun main() { val week = Week(listOf("Mon", "Tue", "Wed", "Thu", "Fri")) println("Wed" in week) // Output: true println("Sun" in week) // Output: false }
Here we create a Week
class that implements contains
.
This allows us to use in
to check if a day is in the week. The
operator provides a natural syntax for this membership check.
Not in Operator
Kotlin also provides the !in
operator to check if a value is not in
a range or collection. This is the logical inverse of the in
operator.
package com.zetcode fun main() { val primes = setOf(2, 3, 5, 7, 11) val num = 4 if (num !in primes) { println("$num is not prime") } val validChars = 'a'..'z' println('$' !in validChars) // Output: true }
We check if 4 is not in a set of prime numbers and if '$' is not in the range of
valid lowercase letters. Both conditions evaluate to true. The !in
operator improves code readability for negative checks.
String Contains Check
The in
operator can check if a substring exists within a string.
This provides a concise alternative to the contains
method.
package com.zetcode fun main() { val message = "Hello Kotlin" if ("Kot" in message) { println("Substring found") } val forbidden = listOf("spam", "ads", "virus") val email = "Buy cheap ads now!" if (forbidden.any { it in email }) { println("Spam detected") } }
We check if "Kot" exists in a string and if any forbidden words appear in an
email. The in
operator makes these checks straightforward. The
second example combines in
with any
for more complex
checks.
Map Key Check
The in
operator can check if a key exists in a map. This provides a
clean way to verify map membership without explicitly calling methods.
package com.zetcode fun main() { val capitals = mapOf( "USA" to "Washington", "UK" to "London", "France" to "Paris" ) if ("France" in capitals) { println("Capital of France is ${capitals["France"]}") } println("Germany" in capitals) // Output: false }
We check if "France" and "Germany" are keys in a map of capitals. The
in
operator makes these checks concise. When checking map keys,
in
is more readable than calling containsKey
.
Best Practices for in Operator
- Prefer in for readability: Use
in
instead ofcontains
when possible for cleaner code. - Combine with ranges: Leverage
in
with range expressions for concise boundary checks. - Implement contains: For custom types, implement
contains
to enablein
operator support. - Use !in for negative checks: The
!in
operator provides clear syntax for absence checks. - Consider performance: For large collections, be aware that
in
may have O(n) complexity unless using a Set.
Source
Kotlin Operator Overloading Documentation
This tutorial covered Kotlin's in
keyword in depth, showing its use
for range checking, collection membership, and iteration. We explored various
scenarios including custom implementations and string operations. The
in
operator provides concise and readable syntax for common
operations.
Author
List all Kotlin tutorials.