Kotlin Help

Strings in Java and Kotlin

This guide contains examples of how to perform typical tasks with strings in Java and Kotlin. It will help you migrate from Java to Kotlin and write your code in the authentically Kotlin way.

Concatenate strings

In Java, you can do this in the following way:

// Java String name = "Joe"; System.out.println("Hello, " + name); System.out.println("Your name is " + name.length() + " characters long");

In Kotlin, use the dollar sign ($) before the variable name to interpolate the value of this variable into your string:

fun main() { //sampleStart // Kotlin val name = "Joe" println("Hello, $name") println("Your name is ${name.length} characters long") //sampleEnd }

You can interpolate the value of a complicated expression by surrounding it with curly braces, like in ${name.length}. See string templates for more information.

Build a string

In Java, you can use the StringBuilder:

// Java StringBuilder countDown = new StringBuilder(); for (int i = 5; i > 0; i--) { countDown.append(i); countDown.append("\n"); } System.out.println(countDown);

In Kotlin, use buildString() – an inline function that takes logic to construct a string as a lambda argument:

fun main() { //sampleStart // Kotlin val countDown = buildString { for (i in 5 downTo 1) { append(i) appendLine() } } println(countDown) //sampleEnd }

Under the hood, the buildString uses the same StringBuilder class as in Java, and you access it via an implicit this inside the lambda.

Learn more about lambda coding conventions.

Create a string from collection items

In Java, you use the Stream API to filter, map, and then collect the items:

// Java List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6); String invertedOddNumbers = numbers .stream() .filter(it -> it % 2 != 0) .map(it -> -it) .map(Object::toString) .collect(Collectors.joining("; ")); System.out.println(invertedOddNumbers);

In Kotlin, use the joinToString() function, which Kotlin defines for every List:

fun main() { //sampleStart // Kotlin val numbers = listOf(1, 2, 3, 4, 5, 6) val invertedOddNumbers = numbers .filter { it % 2 != 0 } .joinToString(separator = ";") {"${-it}"} println(invertedOddNumbers) //sampleEnd }

Learn more about joinToString() usage.

Set default value if the string is blank

In Java, you can use the ternary operator:

// Java public void defaultValueIfStringIsBlank() { String nameValue = getName(); String name = nameValue.isBlank() ? "John Doe" : nameValue; System.out.println(name); } public String getName() { Random rand = new Random(); return rand.nextBoolean() ? "" : "David"; }

Kotlin provides the inline function ifBlank() that accepts the default value as an argument:

// Kotlin import kotlin.random.Random //sampleStart fun main() { val name = getName().ifBlank { "John Doe" } println(name) } fun getName(): String = if (Random.nextBoolean()) "" else "David" //sampleEnd

Replace characters at the beginning and end of a string

In Java, you can use the replaceAll() function. The replaceAll() function in this case accepts regular expressions ^## and ##$, which define strings starting and ending with ## respectively:

// Java String input = "##place##holder##"; String result = input.replaceAll("^##|##$", ""); System.out.println(result);

In Kotlin, use the removeSurrounding() function with the string delimiter ##:

fun main() { //sampleStart // Kotlin val input = "##place##holder##" val result = input.removeSurrounding("##") println(result) //sampleEnd }

Replace occurrences

In Java, you can use the Pattern and the Matcher classes, for example, to obfuscate some data:

// Java String input = "login: Pokemon5, password: 1q2w3e4r5t"; Pattern pattern = Pattern.compile("\\w*\\d+\\w*"); Matcher matcher = pattern.matcher(input); String replacementResult = matcher.replaceAll(it -> "xxx"); System.out.println("Initial input: '" + input + "'"); System.out.println("Anonymized input: '" + replacementResult + "'");

In Kotlin, you use the Regex class that simplifies working with regular expressions. Additionally, use multiline strings to simplify a regex pattern by reducing the count of backslashes:

fun main() { //sampleStart // Kotlin val regex = Regex("""\w*\d+\w*""") // multiline string val input = "login: Pokemon5, password: 1q2w3e4r5t" val replacementResult = regex.replace(input, replacement = "xxx") println("Initial input: '$input'") println("Anonymized input: '$replacementResult'") //sampleEnd }

Split a string

In Java, to split a string with the period character (.), you need to use shielding (\\). This happens because the split() function of the String class accepts a regular expression as an argument:

// Java System.out.println(Arrays.toString("Sometimes.text.should.be.split".split("\\.")));

In Kotlin, use the Kotlin function split(), which accepts varargs of delimiters as input parameters:

fun main() { //sampleStart // Kotlin println("Sometimes.text.should.be.split".split(".")) //sampleEnd }

If you need to split with a regular expression, use the overloaded split() version that accepts the Regex as a parameter.

Take a substring

In Java, you can use the substring() function, which accepts an inclusive beginning index of a character to start taking the substring from. To take a substring after this character, you need to increment the index:

// Java String input = "What is the answer to the Ultimate Question of Life, the Universe, and Everything? 42"; String answer = input.substring(input.indexOf("?") + 1); System.out.println(answer);

In Kotlin, you use the substringAfter() function and don't need to calculate the index of the character you want to take a substring after:

fun main() { //sampleStart // Kotlin val input = "What is the answer to the Ultimate Question of Life, the Universe, and Everything? 42" val answer = input.substringAfter("?") println(answer) //sampleEnd }

Additionally, you can take a substring after the last occurrence of a character:

fun main() { //sampleStart // Kotlin val input = "To be, or not to be, that is the question." val question = input.substringAfterLast(",") println(question) //sampleEnd }

Use multiline strings

Before Java 15, there were several ways to create a multiline string. For example, using the join() function of the String class:

// Java String lineSeparator = System.getProperty("line.separator"); String result = String.join(lineSeparator, "Kotlin", "Java"); System.out.println(result);

In Java 15, text blocks appeared. There is one thing to keep in mind: if you print a multiline string and the triple-quote is on the next line, there will be an extra empty line:

// Java String result = """ Kotlin Java """; System.out.println(result);

The output:

Java 15 multiline output

If you put the triple-quote on the same line as the last word, this difference in behavior disappears.

In Kotlin, you can format your line with the quotes on the new line, and there will be no extra empty line in the output. The left-most character of any line identifies the beginning of the line. The difference with Java is that Java automatically trims indents, and in Kotlin you should do it explicitly:

fun main() { //sampleStart // Kotlin val result = """ Kotlin Java """.trimIndent() println(result) //sampleEnd }

The output:

Kotlin multiline output

To have an extra empty line, you should add this empty line to your multiline string explicitly.

In Kotlin, you can also use the trimMargin() function to customize the indents:

// Kotlin fun main() { val result = """ # Kotlin # Java """.trimMargin("#") println(result) }

Learn more about multiline strings.

What's next?

If you have a favorite idiom, we invite you to share it by sending a pull request.

Last modified: 25 September 2024