ZetCode

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.

RangeCheck.kt
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.

CollectionCheck.kt
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.

Iteration.kt
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.

CustomIn.kt
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.

NotIn.kt
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.

StringContains.kt
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.

MapCheck.kt
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

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

My name is Jan Bodnar, and I am a passionate programmer with many years of programming experience. I have been writing programming articles since 2007. So far, I have written over 1400 articles and 8 e-books. I have over eight years of experience in teaching programming.

List all Kotlin tutorials.