Java 与 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.
字符串连接
In Java, you can do this in the following way:
// JavaString 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// Kotlinval 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.
构建字符串
In Java, you can use the StringBuilder:
// JavaStringBuilder 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// Kotlinval 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.
由集合内元素创建字符串
In Java, you use the Stream API to filter, map, and then collect the items:
// JavaList<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// Kotlinval numbers = listOf(1, 2, 3, 4, 5, 6)val invertedOddNumbers = numbers.filter { it % 2 != 0 }.joinToString(separator = ";") {"${-it}"}println(invertedOddNumbers)//sampleEnd}
In Java, if you want spaces between your delimiters and following items, you need to add a space to the delimiter explicitly.
Learn more about joinToString() usage.
如果字符串为空白就设置默认值
In Java, you can use the ternary operator:
// Javapublic 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:
// Kotlinimport kotlin.random.Random//sampleStartfun main() {val name = getName().ifBlank { "John Doe" }println(name)}fun getName(): String =if (Random.nextBoolean()) "" else "David"//sampleEnd
替换字符串首尾处的(多个)字符
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:
// JavaString input = "##place##holder##";String result = input.replaceAll("^##|##$", "");System.out.println(result);
In Kotlin, use the removeSurrounding() function with the string delimiter ##:
fun main() {//sampleStart// Kotlinval input = "##place##holder##"val result = input.removeSurrounding("##")println(result)//sampleEnd}
正则替换
In Java, you can use the Pattern and the Matcher classes, for example, to obfuscate some data:
// JavaString 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 raw strings to simplify a regex pattern by reducing the count of backslashes:
fun main() {//sampleStart// Kotlinval regex = Regex("""\w*\d+\w*""") // multiline stringval input = "login: Pokemon5, password: 1q2w3e4r5t"val replacementResult = regex.replace(input, replacement = "xxx")println("Initial input: '$input'")println("Anonymized input: '$replacementResult'")//sampleEnd}
字符串拆分
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:
// JavaSystem.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// Kotlinprintln("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.
取子串
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:
// JavaString 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// Kotlinval 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// Kotlinval input = "To be, or not to be, that is the question."val question = input.substringAfterLast(",")println(question)//sampleEnd}
使用多行字符串
Before Java 15, there were several ways to create a multiline string. For example, using the join()) function of the String class:
// JavaString 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:
// JavaString result = """KotlinJava""";System.out.println(result);
The 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// Kotlinval result = """KotlinJava""".trimIndent()println(result)//sampleEnd}
The 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:
// Kotlinfun main() {val result = """# Kotlin# Java""".trimMargin("#")println(result)}
Learn more about multiline strings.
下一步做什么?
- Look through other Kotlin idioms.
- Learn how to convert existing Java code to Kotlin with the Java to Kotlin converter.
If you have a favorite idiom, we invite you to share it by sending a pull request.
