Question

String Concatenation in Kotlin: Using +, Templates, and StringBuilder

kotlinstring

Question

What is the correct way to concatenate strings in Kotlin?

In Java, you can use String.concat():

String a = "Hello ";
String b = a.concat("World"); // "Hello World"

Kotlin does not expose concat() in the same way. Should string concatenation be done with the + operator?

Short Answer

You will learn how Kotlin joins strings with the + operator, how string templates make values easier to embed in text, and when StringBuilder is a better choice for repeated concatenation.

Concept

Kotlin commonly concatenates strings with the + operator:

val message = "Hello " + "World"

The result is a new string, "Hello World".

Kotlin's String values are immutable: once a string is created, its characters cannot be changed. Concatenation therefore creates a new String containing the combined text.

For text that includes variables or expressions, Kotlin usually prefers string templates:

val name = "Ada"
val message = "Hello, $name!"

This is concise and readable. Use braces when the expression is more than a simple variable name:

val itemCount = 3
val message = "You have ${itemCount + 1} items."

For a small number of pieces, + and string templates are clear and appropriate. If you are building a large string repeatedly in a loop, use StringBuilder to avoid creating many intermediate strings.

Mental Model

Think of a String as a printed label. You cannot erase or extend the label after it is printed.

When you write:

val fullName = firstName + " " + lastName

Kotlin produces a new label that contains all three pieces.

A string template is like a label printer with blanks to fill in:

"Welcome, $name"

For many repeated additions, StringBuilder is like writing onto a reusable whiteboard and printing the final label only when you are done.

Take Quiz

Syntax and Examples

Use + to join strings:

val greeting = "Hello " + "World"
println(greeting) // Hello World

+ can combine a string with other values. Kotlin converts the other value to text:

val score = 42
val message = "Score: " + score
println(message) // Score: 42

Prefer string templates when inserting values into text:

val user = "Mina"
val points = 125

val message = "$user has $points points."
println(message) // Mina has 125 points.

Use ${...} for a property access, function call, or calculation:

val product = "notebook"
val quantity = 2

println("Product: ${product.uppercase()}")
println("Total items: ${quantity * 3}")

For many additions, use StringBuilder:

val builder = StringBuilder()

builder.append("Hello")
builder.append(", ")
builder.append("World")

val greeting = builder.toString()
println(greeting) // Hello, World

Step by Step Execution

Consider this code:

val firstName = "Grace"
val lastName = "Hopper"
val fullName = firstName + " " + lastName
val message = "Welcome, $fullName!"

println(message)

Execution proceeds as follows:

  1. firstName refers to the string "Grace".
  2. lastName refers to the string "Hopper".
  3. Kotlin evaluates firstName + " ", producing "Grace ".
  4. It joins that result with lastName, producing a new string: "Grace Hopper".
  5. The template "Welcome, $fullName!" inserts the value of fullName.
  6. println displays:
Welcome, Grace Hopper!

Real World Use Cases

String concatenation and templates are useful whenever an application creates human-readable text.

  • User interface labels:

    val heading = "Welcome back, $displayName"
    
  • API paths and query values:

    val endpoint = "/users/$userId/orders"
    
  • Log messages:

    println("Request failed with status $statusCode")
    
  • Validation feedback:

    val error = "Password must contain at least $minimumLength characters."
    
  • Reports and exports:

    val row = "$customerId,$customerName,$total"
    

For structured formats such as JSON, use a serializer or JSON library rather than manually joining strings. Manual concatenation can create invalid output when values contain quotes, commas, or special characters.

Take Quiz

Real Codebase Usage

In production Kotlin code, developers generally use templates for readable messages and StringBuilder for repeated assembly.

String templates for logs and messages

fun describeOrder(orderId: Long, status: String): String {
    return "Order $orderId is $status"
}

Guard clauses with useful error messages

fun requirePositiveQuantity(quantity: Int) {
    require(quantity > 0) {
        "Quantity must be positive, but was $quantity."
    }
}

The message is created only if the condition fails because require accepts a lambda for its message.

buildString for multiline or conditional text

Kotlin provides buildString, which creates and returns a string using a StringBuilder internally:

fun createProfileSummary(name: String, email: String?, isAdmin: Boolean): String = buildString {
    appendLine("Name: $name")

    if (email != null) {
        appendLine("Email: $email")
    }

    if (isAdmin) {
        append("Role: administrator")
    }
}

This pattern is useful when parts of the output depend on conditions or are added in a loop.

Repeated output in a loop

val csv = buildString {
    for (name in listOf("Ana", "Bo", "Chen")) {
        appendLine(name)
    }
}

This avoids repeatedly assigning a larger and larger immutable string.

Common Mistakes

Expecting a string to change

Strings are immutable. This does not modify message:

val message = "Hello"
// message += " World" // Error: val cannot be reassigned

Use a new val or a mutable var when reassignment is genuinely needed:

var message = "Hello"
message += " World"

For repeated changes, prefer StringBuilder or buildString.

Forgetting spaces and punctuation

Concatenation does not insert separators automatically:

val broken = "Hello" + "World"
println(broken) // HelloWorld

Add the separator yourself:

val correct = "Hello " + "World"

Using $value for a complex expression

A simple name works after $, but expressions need braces:

val count = 4

// println("Next: $count + 1") // Prints: Next: 4 + 1
println("Next: ${count + 1}") // Prints: Next: 5

Concatenating repeatedly in a large loop

This works but can create many intermediate strings:

var report = ""
for (number in 1..10_000) {
    report += "$number\n"
}

Use buildString instead:

val report = buildString {
    for (number in 1..10_000) {
        appendLine(number)
    }
}

Building JSON manually

This is unsafe if name contains quotes or special characters:

val json = "{\"name\": \"$name\"}"

Use a JSON serialization library for JSON data.

Comparisons

ApproachBest forExampleNotes
+Joining a few pieces of text"Hello " + nameClear for simple cases.
String templateText containing values"Hello, $name"Usually the most readable Kotlin style.
${...} templateExpressions and calls"Total: ${price * quantity}"Braces are required around non-simple expressions.
StringBuilderMany incremental additionsbuilder.append(line)Efficient when adding text repeatedly.
buildStringKotlin-friendly conditional or loop-based constructionbuildString { append(name) }Convenient wrapper around StringBuilder.

Java's String.concat() joins exactly two strings:

String result = "Hello ".concat("World");

In Kotlin, use + or a template instead:

val result = "Hello " + "World"
val sameResult = "Hello World"

Kotlin can call many Java methods when interoperating with Java code, but + and templates are the idiomatic choices for normal Kotlin string construction.

Take Quiz

Cheat Sheet

// Join strings
val text = "Hello " + "World"

// Insert a variable
val message = "Hello, $name"

// Insert an expression, property, or function result
val total = "Total: ${price * quantity}"
val upper = "Name: ${name.uppercase()}"

// Build text in a loop or with conditions
val output = buildString {
    appendLine("Header")
    append("Footer")
}
  • String is immutable; concatenation creates a new string.
  • Use + for a few values.
  • Prefer templates for messages containing variables.
  • Use ${...} for calculations, calls, and anything more than a simple variable name.
  • Use StringBuilder or buildString for many repeated additions.
  • Add spaces, commas, and newlines explicitly; Kotlin does not add them automatically.

FAQ

Is + the correct way to concatenate strings in Kotlin?

Yes. + is the standard choice for joining a small number of strings. String templates are often even more readable when values are embedded in text.

Does Kotlin have String.concat()?

Kotlin code typically uses + rather than concat(). When working with Java APIs, some Java string functionality may be accessible, but it is not the usual Kotlin style.

Should I use + or string templates in Kotlin?

Use + when joining separate pieces. Use templates when writing a sentence, label, log message, or other text containing values.

val path = "/users/" + userId
val message = "User ID: $userId"

When should I use ${} in a Kotlin string template?

Use ${} for expressions, method calls, and calculations.

val label = "Length: ${name.length}"

Is + slow for Kotlin strings?

It is fine for a small number of concatenations. For repeated concatenation in a large loop, use StringBuilder or buildString.

Can I concatenate a string and an integer in Kotlin?

Yes.

val message = "Attempt: " + 3

A template is often cleaner:

val message = "Attempt: $attempt"

Does + add a space between strings?

No. Add spaces or other separators explicitly.

val fullName = "$firstName $lastName"
Take Quiz

Mini Project

Description

Create a receipt formatter for a small checkout flow. The formatter combines item information, calculates totals, and conditionally adds a discount line. It demonstrates string templates for normal text and buildString for constructing several lines of output.

Goal

Generate a readable, multiline receipt from a product name, quantity, unit price, and optional discount.

Requirements

  • Accept a product name, quantity, unit price, and discount percentage.
  • Calculate the subtotal and final total.
  • Include the product, quantity, and subtotal in the receipt.
  • Include a discount line only when the discount is greater than zero.
  • Return the finished receipt as one multiline string.
Take Quiz

Keep learning

Related questions

View more