skip to content

Walk through the core mutating operations of StringBuilder — append, insert, and deleteAt — including their index semantics and what happens with out-of-range indices.

level: middleimportance: should knowfreq 45%

answer

  1. append = end, overloaded, null -> "null"
  2. insert(index,..) shifts right, index 0..length
  3. deleteAt(index) one char, 0 until length
  4. delete(start,end) half-open range
  5. Bad index -> IndexOutOfBoundsException

basics

~10 s

append adds to the end. insert puts characters at a given position, shifting the rest right. deleteAt removes the single character at an index. Bad indices throw an IndexOutOfBoundsException.

solid answer

~40 s

`append` writes to the end of the buffer and is heavily overloaded — it accepts `String`, `Char`, `CharSequence`, `Any?` (calls `toString()`, printing `null` for null), and primitives like `Int`/`Boolean`. `insert(index, value)` shifts existing characters right and inserts `value` starting at `index`; `index` is valid in `0..length` (so `length` means append at the end). `deleteAt(index)` removes the single char at `index`, valid in `0 until length`. There's also `delete(start, end)` for a half-open range `[start, end)`, `setCharAt(index, char)` to overwrite, and `replace(start, end, str)`. All of `insert`, `deleteAt`, and `setCharAt` throw `IndexOutOfBoundsException` (or `StringIndexOutOfBoundsException` on JVM) for invalid indices. Each call returns the same builder for `insert`/`append` (fluent chaining), while `deleteAt` also returns the builder.

code

kotlin · 6 lines
kotlin
val sb = StringBuilder("Hello")
sb.append(", world")       // "Hello, world"
sb.insert(0, ">> ")        // ">> Hello, world"
sb.deleteAt(sb.length - 1) // drop last char -> ">> Hello, worl"
sb.replace(0, 3, "** ")    // "** Hello, worl"
println(sb.toString())

go deeper

for a junior

Knows append adds to the end and deleteAt removes a char; can use them in simple code.

for a middle

States exact index ranges for insert vs deleteAt, that insert shifts, and that bad indices throw IndexOutOfBoundsException.

for a senior

Adds delete/replace/setCharAt semantics, the null-renders-as-"null" overload behavior, and length vs capacity distinction.

for a principal

Reasons about API design (fluent chaining returning this), JVM-specific StringIndexOutOfBoundsException, and chooses operations to minimize shifting cost in hot paths.

## append — grow at the end `append` is the workhorse. It is overloaded for many types and always writes to the **end** of the builder, returning `this` so calls chain: ```kotlin val sb = StringBuilder() sb.append("x") // String .append('=') // Char .append(42) // Int .append(true) // Boolean .append(null as Any?) // appends the text "null" // sb -> "x=42truenull" ``` For `Any?`, `append` calls `toString()`; a null reference appends the four characters `null`. `appendLine()` appends content followed by the platform line separator. ## insert — add in the middle `insert(index, value)` inserts at position `index`, shifting everything from `index` onward to the right. The valid range is `0..length` (inclusive of `length`, which is equivalent to appending): ```kotlin val sb = StringBuilder("ac") sb.insert(1, 'b') // -> "abc" sb.insert(3, "!") // index == length, appends -> "abc!" ``` ## deleteAt and delete — remove `deleteAt(index)` removes exactly one character; valid `0 until length`. `delete(start, end)` removes the half-open range `[start, end)`: ```kotlin val sb = StringBuilder("abcd") sb.deleteAt(0) // -> "bcd" sb.delete(1, 3) // removes indices 1,2 -> "b" ``` ## Overwrite and replace ```kotlin val sb = StringBuilder("cat") sb.setCharAt(0, 'b') // -> "bat" sb.replace(1, 3, "ig") // replace [1,3) -> "big" ``` ## Out-of-range behavior Invalid indices throw an `IndexOutOfBoundsException` (on the JVM specifically a `StringIndexOutOfBoundsException`, a subclass). Remember the boundary difference: - `insert`: index in `0..length` (length allowed). - `deleteAt` / `setCharAt`: index in `0 until length` (length NOT allowed). ## length and capacity `length` is the current character count; `setLength(n)` truncates or zero-pads. `capacity` is the size of the backing array (>= length) and grows automatically. You usually only care about `length`; capacity is an internal allocation detail you can pre-set via the `StringBuilder(capacity)` constructor.

  • What does `append(null)` put into the builder?
    The literal four-character text "null" — the Any? overload calls toString() and null is rendered as "null", not skipped.
  • Difference between deleteAt and delete?
    deleteAt removes one character at a single index; delete(start, end) removes a half-open range [start, end).

saying these in an interview costs you the question

  • Thinking insert overwrites instead of shifting right
  • Believing deleteAt accepts index == length
  • Expecting append(null) to be a no-op
  • Confusing delete's end as inclusive
  • Saying out-of-range indices are silently ignored

context