Question

Kotlin Case-Insensitive String Comparison with equals

kotlinandroid

Question

What is the Kotlin equivalent of Java's String.equalsIgnoreCase() for comparing two String values without considering letter case?

Using equals normally is case-sensitive. For example:

val first = "Hello"
val second = "hello"

println(first == second) // false

Short Answer

Kotlin provides case-insensitive string comparison through String.equals(other, ignoreCase = true). You will learn how to use it safely, how it differs from ==, and where this comparison is useful in application code.

Concept

Kotlin does not use a separate equalsIgnoreCase() method like Java. Instead, String.equals accepts an optional named argument:

first.equals(second, ignoreCase = true)

This returns true when the strings contain the same characters while ignoring differences such as uppercase and lowercase letters.

By default, Kotlin string equality is case-sensitive:

"Kotlin" == "kotlin" // false

Case-insensitive equality is useful when a user can reasonably enter the same value with different capitalization, such as a command ("START", "start") or an HTTP header name.

Use case-insensitive comparison only when letter case does not carry meaning in your domain. Passwords, IDs, tokens, file checksums, and many user names should usually remain case-sensitive.

Mental Model

Think of a normal string comparison as comparing two labels character by character, including their exact capitalization. "Admin" and "admin" have different labels because the first letter is different.

With ignoreCase = true, the comparison temporarily reads both labels without caring whether each letter is written as uppercase or lowercase. The words must still have the same letters in the same order:

  • "YES" and "yes" match.
  • "yes" and "yep" do not match.
  • "yes" and " yes" do not match because whitespace is still a character.
Take Quiz

Syntax and Examples

Use equals with ignoreCase = true:

val expectedRole = "admin"
val enteredRole = "ADMIN"

val isAdmin = expectedRole.equals(enteredRole, ignoreCase = true)
println(isAdmin) // true

The first string calls equals, and the second string is passed as other.

You can also write it with an explicit parameter name for readability:

val matches = "open".equals(other = "OPEN", ignoreCase = true)
println(matches) // true

Normal equality with == remains case-sensitive:

println("open" == "OPEN") // false

For user input, remove unwanted surrounding whitespace before comparing:

val command = "  Quit  "

if (command.trim().equals("quit", ignoreCase = true)) {
    println("Closing the application")
}

Step by Step Execution

Consider this code:

val userInput = "  YeS "
val answer = userInput.trim()
val accepted = answer.equals("yes", ignoreCase = true)

println(accepted)

Execution:

  1. userInput stores the text " YeS ", including spaces at both ends.
  2. trim() removes leading and trailing whitespace, so answer becomes "YeS".
  3. equals("yes", ignoreCase = true) compares "YeS" and "yes" without treating Y and y, or S and s, as different.
  4. Both strings otherwise have the same characters, so accepted becomes true.
  5. The program prints true.

Without trim(), the result would be false because the spaces are not ignored by equals.

Real World Use Cases

  • Command-line tools: Accept help, HELP, or Help as the same command.
  • Form input: Match a selected plan such as "free" regardless of how a user typed it.
  • HTTP-related code: Header field names are commonly treated case-insensitively.
  • Configuration values: Read values such as "development" and "DEVELOPMENT" when the configuration format allows it.
  • Data import scripts: Match category names from inconsistent external CSV files.

Example command handling:

fun isQuitCommand(input: String): Boolean {
    return input.trim().equals("quit", ignoreCase = true)
}

println(isQuitCommand("QUIT"))  // true
println(isQuitCommand(" quit ")) // true
Take Quiz

Real Codebase Usage

In production code, developers often combine normalization and case-insensitive comparison at an application boundary, where input enters the system.

A guard clause makes invalid input easy to handle:

fun processAction(action: String) {
    val normalizedAction = action.trim()

    if (!normalizedAction.equals("delete", ignoreCase = true)) {
        return
    }

    println("Deleting the item")
}

For a small fixed set of commands, normalize once and use when:

fun commandMessage(input: String): String {
    return when (input.trim().lowercase()) {
        "start" -> "Starting"
        "stop" -> "Stopping"
        "status" -> "Checking status"
        else -> "Unknown command"
    }
}

This pattern is useful when there are several branches. For one direct comparison, equals(..., ignoreCase = true) is usually clearer because it states the intent directly.

When a value can be absent, use a null-safe call:

fun isEnabled(value: String?): Boolean {
    return value?.equals("enabled", ignoreCase = true) == true
}

If value is null, the expression evaluates to false without throwing an exception.

Common Mistakes

Expecting == to ignore case

val same = "Admin" == "admin" // false

== checks structural equality, but string structural equality is still case-sensitive. Use:

val same = "Admin".equals("admin", ignoreCase = true) // true

Looking for equalsIgnoreCase()

This is Java syntax, not Kotlin's usual API style:

// "Admin".equalsIgnoreCase("admin")

In Kotlin, use the ignoreCase parameter:

"Admin".equals("admin", ignoreCase = true)

Forgetting whitespace

" yes ".equals("yes", ignoreCase = true) // false

Case-insensitive does not mean whitespace-insensitive. Normalize input when appropriate:

" yes ".trim().equals("yes", ignoreCase = true) // true

Calling a method on a nullable value

val input: String? = null
// input.equals("yes", ignoreCase = true)

A nullable receiver cannot be used this way. Use a safe call:

val matches = input?.equals("yes", ignoreCase = true) == true

Lowercasing values unnecessarily

val matches = input.lowercase() == "yes"

This can work for simple cases, but it creates a transformed string and can be less expressive for one comparison. Prefer:

val matches = input.equals("yes", ignoreCase = true)

Use lowercase() when you need a normalized value for several comparisons or a when expression.

Comparisons

ApproachCase-insensitive?Best use
first == secondNoExact string equality
first.equals(second, ignoreCase = true)YesOne direct comparison
first.lowercase() == second.lowercase()YesNormalizing both values for additional work
when (input.lowercase())YesSelecting from several known commands

equals(..., ignoreCase = true) is generally the most direct Kotlin equivalent of Java's equalsIgnoreCase().

Be careful with lowercase() for comparisons: it may be appropriate for command keywords, but you should not normalize sensitive values such as passwords merely to compare them.

Take Quiz

Cheat Sheet

// Case-sensitive equality
val exactMatch = first == second

// Case-insensitive equality
val sameText = first.equals(second, ignoreCase = true)

// Nullable input: true only when it is a case-insensitive match
val isYes = input?.equals("yes", ignoreCase = true) == true

// Ignore surrounding input whitespace too
val isQuit = input.trim().equals("quit", ignoreCase = true)

Rules:

  • == is case-sensitive for strings.
  • Kotlin's equivalent of Java equalsIgnoreCase() is equals(other, ignoreCase = true).
  • ignoreCase does not ignore spaces, punctuation, or different characters.
  • Use trim() only if surrounding whitespace should not matter.
  • Avoid case-insensitive comparison for secrets and values whose case is meaningful.

FAQ

What is the Kotlin equivalent of equalsIgnoreCase()?

Use first.equals(second, ignoreCase = true).

Does Kotlin == ignore uppercase and lowercase letters?

No. == compares strings case-sensitively, so "A" == "a" is false.

Can I compare a nullable Kotlin string ignoring case?

Yes. Use value?.equals("text", ignoreCase = true) == true. It returns false when value is null.

Should I use lowercase() instead of equals(ignoreCase = true)?

For one equality check, equals(ignoreCase = true) is clearer. Use lowercase() when you want to normalize once and compare against multiple options.

Does ignoreCase = true ignore whitespace?

No. " yes " and "yes" are different. Call trim() first if the whitespace is not meaningful.

Is case-insensitive comparison safe for passwords?

No. Passwords and other secrets should normally be case-sensitive and handled by an appropriate authentication system.

Can I use this for a when expression?

A when expression does not have an ignoreCase option. Normalize the input first, such as when (input.trim().lowercase()).

Take Quiz

Mini Project

Description

Build a small command interpreter for a console-style application. Users should be able to type commands with any capitalization and accidental spaces, such as HELP, help, or Quit. This demonstrates practical input normalization and case-insensitive string handling.

Goal

Create a function that recognizes help, status, and quit commands regardless of letter case.

Requirements

Normalize leading and trailing whitespace from the input. Accept help, status, and quit regardless of capitalization. Return a different message for each recognized command. Return an unknown-command message for every other value. Do not treat partial words such as helper as valid commands.

Take Quiz

Keep learning

Related questions

View more