Explain isBlank/isEmpty, ifBlank/ifEmpty, and padStart/padEnd. How do they differ and how do they compose for input normalization?
answer
- isEmpty = length 0; isBlank = whitespace-only too
- ifBlank/ifEmpty take a lazy fallback lambda
- padStart prepends, padEnd appends, never truncates
- Nullable helpers: isNullOrBlank/isNullOrEmpty
- Negative pad length throws
basics
~10 sisEmpty checks for zero length; isBlank also treats whitespace-only as empty. ifBlank/ifEmpty give a fallback value when the string is blank/empty. padStart/padEnd add filler characters to reach a target width.
solid answer
~40 sisEmpty() is true only when length == 0; isBlank() is true when the string has no non-whitespace characters (so " ".isBlank() is true but isEmpty() is false). ifEmpty { } / ifBlank { } take a lambda producing a fallback and return it when the receiver is empty/blank, otherwise return the receiver — perfect with Elvis-like defaulting. padStart(length, padChar = ' ') prepends the pad char until the string reaches the target length (no-op if already longer); padEnd appends. Common composition: normalize user input via trim().ifBlank { default } and format fixed-width fields with padStart(8, '0'). There are also negated forms isNotEmpty()/isNotBlank() and the nullable-friendly isNullOrEmpty()/isNullOrBlank() that handle a String? in one call.
code
kotlin · 8 linesfun displayName(raw: String?): String =
raw?.trim()?.ifBlank { "Anonymous" } ?: "Anonymous"
fun invoiceNo(seq: Int): String = seq.toString().padStart(8, '0')
println(displayName(" ")) // Anonymous
println(displayName(" Ada ")) // Ada
println(invoiceNo(42)) // 00000042go deeper
Distinguishes isEmpty (length 0) from isBlank (whitespace-only) and uses padStart for zero-padding.
Composes trim().ifBlank { } for input normalization and knows pad never truncates plus the nullable helpers.
Chooses blank-vs-empty semantics deliberately per domain, leverages laziness of ifBlank, and handles String? cleanly.
Defines team-wide input normalization conventions (trim/blank/default) and fixed-width formatting standards to avoid inconsistent validation.
## Emptiness vs blankness - `String.isEmpty(): Boolean` — true iff `length == 0`. - `String.isBlank(): Boolean` — true iff the string contains **only whitespace** (or is empty). Whitespace is determined by `Char.isWhitespace()`. ```kotlin "".isEmpty() // true "".isBlank() // true " ".isEmpty() // false <-- has length " ".isBlank() // true <-- only whitespace ``` Negations and nullable forms exist: `isNotEmpty()`, `isNotBlank()`, and on `String?`: `isNullOrEmpty()`, `isNullOrBlank()` (true when the receiver is null *or* empty/blank), which also smart-cast the value to non-null in the `false` branch. ## Defaulting: ifEmpty / ifBlank ```kotlin fun String.ifEmpty(defaultValue: () -> CharSequence): CharSequence fun String.ifBlank(defaultValue: () -> CharSequence): CharSequence ``` They return the receiver if it is **not** empty/blank, otherwise the lambda's result. The lambda is **lazy** — it only runs when needed. ```kotlin val name = rawName.trim().ifBlank { "Anonymous" } val csv = items.ifEmpty { "<no rows>" } ``` ## Padding: padStart / padEnd ```kotlin fun String.padStart(length: Int, padChar: Char = ' '): String fun String.padEnd(length: Int, padChar: Char = ' '): String ``` - `padStart` prepends `padChar` until the result reaches `length`; `padEnd` appends. - If the string is already at least `length`, it is returned **unchanged** (never truncates). - A negative `length` throws `IllegalArgumentException`. ```kotlin "42".padStart(5, '0') // "00042" "NAME".padEnd(8) // "NAME " "toolong".padStart(3) // "toolong" (unchanged) ``` ## Composing for normalization ```kotlin fun normalizeUsername(input: String?): String = input?.trim()?.ifBlank { null } ?: "guest" fun ticket(n: Int): String = "#" + n.toString().padStart(6, '0') // "#000007" ``` Use `isBlank`/`ifBlank` for **user input** (whitespace usually means "nothing"); use `isEmpty`/`ifEmpty` when the exact zero-length distinction matters (e.g., a deliberately empty field vs. spaces).
- Why prefer isNullOrBlank() over s == null || s.isBlank()?It is one concise call and smart-casts s to non-null String in the false branch, so the compiler lets you use it without further null checks.
- Does padStart ever shorten a string?No. If the string already meets or exceeds the target length, padStart/padEnd return it unchanged; they only add characters.
saying these in an interview costs you the question
- Treating isEmpty and isBlank as identical
- Thinking padStart truncates when the string is too long
- Forgetting the ifBlank lambda is lazy (no eager allocation)
- Hand-rolling null+blank checks instead of isNullOrBlank