Text is everywhere in programs: names, messages, file contents, web addresses, search terms. In Kotlin, text is a String, written between double quotes.
Kotlin makes working with strings especially pleasant. Instead of gluing pieces together with +, you write string templates: put $name inside the quotes, and Kotlin inserts the variable's value. Strings also come with dozens of built-in functions to change case, trim spaces, search, replace, cut out parts and split text into lists.
In this lesson you'll build messages with templates, read individual characters, use the most common string functions, split and join text, and write multi-line text with raw strings. Strings in Kotlin are immutable: functions like uppercase() return a new string and leave the original unchanged.
String templates
val name = "Sam"
val items = 3
println("Hi $name, you have $items items")
println("Next year you'll be ${age + 1}")
println("Name has ${name.length} letters")$nameinserts a simple variable.${ ... }inserts the result of any expression, such as a calculation or a function call.- To print a literal dollar sign, write
\$or${'$'}.
Templates are clearer than joining with +, and Kotlin converts numbers and other values to text automatically.
Length, characters and indexes
text.lengthis the number of characters.text[0]is the first character, aChar;text[text.length - 1]ortext.last()is the last.- Indexes start at 0, so a 5-letter word has indexes 0 to 4.
text.substring(0, 3)returns the characters from index 0 up to, but not including, 3.text.take(3)andtext.takeLast(3)give the first or last three characters, without crashing if the string is shorter.
Common string functions
| Function | Example | Result |
|---|---|---|
uppercase() / lowercase() | "Kotlin".uppercase() | "KOTLIN" |
trim() | " hi ".trim() | "hi" |
contains(x) | "kotlin".contains("tli") | true |
startsWith(x) / endsWith(x) | "photo.png".endsWith(".png") | true |
replace(a, b) | "a-b-c".replace("-", "/") | "a/b/c" |
indexOf(x) | "banana".indexOf("n") | 2 |
isBlank() | " ".isBlank() | true |
replaceFirstChar { it.uppercase() } | "london" | "London" |
Many functions take an ignoreCase = true argument, such as "KOTLIN".contains("kot", ignoreCase = true).
Splitting, joining and raw strings
split(",") turns a string into a list, and joinToString(", ") turns a list back into a string. Together they handle comma-separated values, tags and words.
A raw string uses triple quotes. It can span several lines and doesn't process escape sequences such as \n, which is handy for file paths, JSON and long messages. trimIndent() removes the indentation you added to keep the code tidy:
val message = """
Dear $name,
Your order has shipped.
""".trimIndent()Templates still work inside raw strings.
Building strings efficiently
Strings are immutable: every + creates a new string. That's fine for a few pieces, but inside a loop that runs thousands of times it creates a lot of throwaway objects. Kotlin's buildString gives you a changeable buffer and returns the finished string:
val receipt = buildString {
appendLine("Receipt")
for ((item, price) in listOf("Tea" to 2.5, "Cake" to 3.2)) {
appendLine("$item: £$price")
}
append("Thank you!")
}
println(receipt)Inside the braces you call append and appendLine directly. For a list of values with separators, joinToString is even simpler: listOf("a", "b", "c").joinToString(", ") gives "a, b, c", and it accepts a prefix, postfix and a transform lambda.
To compare text while ignoring capital letters, use equals with a named argument: "Kotlin".equals("kotlin", ignoreCase = true) is true. Many other functions, such as contains and startsWith, accept ignoreCase = true too.
Kotlin Strings Syntax
String essentials
val s = "Hello, $name! You are ${age + 1} next year."
s.length s[0] s.substring(0, 5) s.take(3)
s.uppercase() s.trim() s.replace("a", "b")
s.contains("x") s.startsWith("x") s.split(",")
listOf("a", "b").joinToString(", ")
"""multi
line""".trimIndent()
a == b a.equals(b, ignoreCase = true)Kotlin Strings Summary
- Strings use double quotes;
$nameand${expression}insert values into them. - Indexes start at 0;
length,[i],substring,takeandtakeLastread parts. - uppercase, trim, contains, replace and startsWith return new strings or answers.
- split makes a list; joinToString makes a string from a list.
- Triple-quoted raw strings span lines; trimIndent tidies their indentation.
Kotlin Strings Examples
Each example shows the code, the output it produces and what each part does.
Templates and string functions
fun main() {
val first = " ada "
val last = "LOVELACE"
val clean = first.trim().replaceFirstChar { it.uppercase() }
val full = "$clean ${last.lowercase().replaceFirstChar { it.uppercase() }}"
println(full)
println("${full.length} characters")
println(full.uppercase())
println(full.contains("love", ignoreCase = true))
}Ada Lovelace
12 characters
ADA LOVELACE
trueLine-by-line explanation
- Line 4trim removes the spaces, then the first letter is capitalised.
- Line 5A template joins the two cleaned names with a space.
- Line 8${ } inserts an expression's result.
- Line 10ignoreCase makes "love" match "Love".
Characters and substrings
fun main() {
val code = "KT-2024-UK"
println(code[0])
println(code.last())
println(code.substring(3, 7))
println(code.take(2))
println(code.takeLast(2))
println(code.indexOf("UK"))
}K
K
2024
KT
UK
8Line-by-line explanation
- Line 3Index 0 is the first character.
- Line 4last() is the final character, also a K here.
- Line 5Indexes 3 to 6; the end index 7 isn't included.
- Line 8"UK" starts at index 8.
Splitting, joining and a raw string
fun main() {
val input = "kotlin, android, coroutines"
val tags = input.split(",").map { it.trim() }
println(tags)
println(tags.joinToString(" | "))
val user = "Sam"
val email = """
Hi $user,
Your tags: ${tags.size}
Thanks!
""".trimIndent()
println(email)
}[kotlin, android, coroutines]
kotlin | android | coroutines
Hi Sam,
Your tags: 3
Thanks!Line-by-line explanation
- Line 3split makes a list; map with trim tidies each piece (you'll learn map in the collections lessons).
- Line 5joinToString joins the list with a new separator.
- Lines 8 to 12A raw string spans lines, templates still work, and trimIndent removes the shared indentation.
Common Kotlin Strings Mistakes
Expecting a function to change the string
val city = "london"
city.uppercase()
println(city) // londonval city = "london".uppercase()
println(city) // LONDONIndex out of range
val word = "Hi"
println(word.substring(0, 5)) // StringIndexOutOfBoundsExceptionprintln(word.take(5)) // HiBraces missing in a template
println("Total: $price * qty") // Total: 4.5 * qtyprintln("Total: ${price * qty}") // Total: 9.0Without braces, only the variable name is inserted; the rest is plain text.
Kotlin Strings in Real Projects
Strings in apps
Android apps build screen text with templates, clean up what users type with trim(), validate input with functions like contains("@"), and split CSV or search queries into lists. Raw strings are popular for embedding JSON in tests and SQL queries in database code, where escaping every quote would be painful.
Kotlin Strings FAQ
Are Kotlin strings mutable?
No. A String never changes after it's created; functions such as uppercase() and replace() return a new string. Assign the result, name = name.trim(), to keep it, and use buildString or StringBuilder when building text piece by piece.
What is the difference between == and === for strings?
== compares the text, so two strings with the same characters are equal. === checks whether two variables point to the very same object, which is rarely what you want for text. Use == for string comparisons in Kotlin.
How do I check whether a string is empty or blank?
isEmpty() is true for "", and isBlank() is also true for strings containing only spaces or tabs. For values that might be null, isNullOrEmpty() and isNullOrBlank() handle the null case too, which makes them handy for form input.
How do I reverse a string in Kotlin?
Call reversed(): "Hello".reversed() returns "olleH". It reverses UTF-16 characters, so text with emoji or combined accents may not reverse perfectly; for ordinary words it works as expected.
How do I remove indentation from a multi-line string?
Raw strings keep the spaces from your source code. Call trimIndent() to remove the common indentation from every line, or put a | at the start of each line and call trimMargin(), which removes everything up to and including the |.
Kotlin Strings Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Complete the template so it prints "Hello, Ada".
val name = "Ada"
println("Hello, ")
What does println("Kotlin".length) print?
What does this print?
val s = "banana"
println(s.substring(1, 4))
Which line prints "Total: 15"?
What does this print?
val parts = "a-b-c".split("-")
println(parts.joinToString(""))
Kotlin Strings Quiz
5 questions to check what you learned.
What is the index of the first character in a string?
- 1
- 0
- -1
- It depends on the string
What does
" hi ".trim()return?- " hi"
- "hi "
- " hi "
- "hi"
What does
"ABC".lowercase()do to the original string?- Changes it to "abc"
- Nothing; it returns a new string "abc"
- Deletes it
- Throws an error
What is a raw string?
- A triple-quoted string that can span lines and doesn't process escapes like \n
- A string without a type
- An encrypted string
- A string of numbers only
How do you compare two strings while ignoring case?
- a == b
- a.compare(b)
- a.equals(b, ignoreCase = true)
- a === b