Строки в Java и Kotlin
В этом руководстве содержатся примеры выполнения типичных задач со строками в Java и Kotlin. Оно поможет вам перейти с Java на Kotlin и писать код в подлинно Kotlin-стиле.
Конкатенация строк
В Java это можно сделать следующим образом:
// Java
String name = "Joe";
System.out.println("Hello, " + name);
System.out.println("Your name is " + name.length() + " characters long");
В Kotlin используйте знак доллара ($) перед именем переменной для интерполяции значения этой переменной в вашу строку:
fun main() {
//sampleStart
// Kotlin
val name = "Joe"
println("Hello, $name")
println("Your name is ${name.length} characters long")
//sampleEnd
}
Вы можете интерполировать значение сложного выражения, заключив его в фигурные скобки, как в ${name.length}. Подробнее об этом см. в разделе шаблоны строк.
Создание строки
В Java можно использовать StringBuilder:
// Java
StringBuilder countDown = new StringBuilder();
for (int i = 5; i > 0; i--) {
countDown.append(i);
countDown.append("\n");
}
System.out.println(countDown);
В Kotlin используйте buildString() — встроенную функцию, которая принимает логику построения строки в качестве лямбда-аргумента:
fun main() {
//sampleStart
// Kotlin
val countDown = buildString {
for (i in 5 downTo 1) {
append(i)
appendLine()
}
}
println(countDown)
//sampleEnd
}
Под капотом buildString использует тот же класс StringBuilder, что и в Java, и вы получаете к нему доступ через неявный this внутри лямбды.
Узнайте больше о правилах кодирования для лямбд.
Создание строки из элементов коллекции
В Java используйте Stream API для фильтрации, преобразования и последующего сбора элементов:
// 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);
В Kotlin используйте функцию joinToString(), которую Kotlin определяет для каждого списка:
fun main() {
//sampleStart
// Kotlin
val numbers = listOf(1, 2, 3, 4, 5, 6)
val invertedOddNumbers = numbers
.filter { it % 2 != 0 }
.joinToString{ "${-it}" }
println(invertedOddNumbers)
//sampleEnd
}
Узнайте больше о применении joinToString().
Установить значение по умолчанию, если строка пуста
В Java можно использовать тернарный оператор:
// 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 предоставляет встроенную функцию ifBlank(), которая принимает значение по умолчанию в качестве аргумента:
// 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
Замена символов в начале и конце строки
В Java можно использовать функции replaceFirst() и replaceAll(). В этом случае функция replaceAll() принимает регулярное выражение ##$, которое определяет строку, заканчивающуюся на ##.
// Java
String input = "##place##holder##";
String result = input.replaceFirst("##", "").replaceAll("##$", "");
System.out.println(result);
В Kotlin используйте функцию removeSurrounding() с разделителем строки ##.
fun main() {
//sampleStart
// Kotlin
val input = "##place##holder##"
val result = input.removeSurrounding("##")
println(result)
//sampleEnd
}
Замена вхождений
В Java можно использовать классы Pattern и Matcher, например, для обфускации данных:
// 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 + "'");
В Kotlin используется класс Regex, который упрощает работу с регулярными выражениями. Кроме того, используйте сырые строки для упрощения шаблона регулярного выражения, уменьшив количество обратных слэшей:
fun main() {
//sampleStart
// Kotlin
val regex = Regex("""\w*\d+\w*""") // raw string
val input = "login: Pokemon5, password: 1q2w3e4r5t"
val replacementResult = regex.replace(input, replacement = "xxx")
println("Initial input: '$input'")
println("Anonymized input: '$replacementResult'")
//sampleEnd
}
Разделение строки
В Java для разделения строки с точкой (.) необходимо использовать экранирование (\\). Это происходит потому, что функция split() класса String принимает регулярное выражение в качестве аргумента:
// Java
System.out.println(Arrays.toString("Sometimes.text.should.be.split".split("\\.")));
В Kotlin используйте функцию Kotlin split(), которая принимает в качестве входных параметров параметры varargs разделителей:
fun main() {
//sampleStart
// Kotlin
println("Sometimes.text.should.be.split".split("."))
//sampleEnd
}
Если вам нужно разделить по регулярному выражению, используйте перегруженную split() версию, которая принимает Regex в качестве параметра.
Извлечение подстроки
В Java можно использовать функцию substring(), которая принимает инклюзивный начальный индекс символа, с которого начинается извлечение подстроки. Чтобы извлечь подстроку после этого символа, необходимо увеличить индекс:
// 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);
В Kotlin используйте функцию substringAfter() и не нужно вычислять индекс символа, после которого вы хотите извлечь подстроку:
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
}
Кроме того, можно извлечь подстроку после последнего вхождения символа:
fun main() {
//sampleStart
// Kotlin
val input = "To be, or not to be, that is the question."
val question = input.substringAfterLast(",")
println(question)
//sampleEnd
}
Использование многострочных строк
До Java 15 существовало несколько способов создания многострочных строк. Например, использование функции join() класса String.
// Java
String lineSeparator = System.getProperty("line.separator");
String result = String.join(lineSeparator,
"Kotlin",
"Java");
System.out.println(result);
В Java 15 появились текстовые блоки. Важно помнить, что если вы выводите многострочную строку, а тройная кавычка находится на следующей строке, то будет дополнительная пустая строка:
// Java
String result = """
Kotlin
Java
""".stripIndent();
System.out.println(result);
Вывод:
Если вы поместите тройную кавычку в той же строке, что и последнее слово, эта разница в поведении исчезает.
В Kotlin вы можете форматировать свою строку с кавычками на новой строке, и в выводе не будет дополнительной пустой строки. Самый левый символ любой строки определяет начало строки.
fun main() {
//sampleStart
// Kotlin
val result = """
Kotlin
Java
""".trimIndent()
println(result)
//sampleEnd
}
Вывод:
В Kotlin также можно использовать функцию trimMargin() для настройки отступов:
// Kotlin
fun main() {
val result = """
# Kotlin
# Java
""".trimMargin("#")
println(result)
}
Узнайте больше о многострочных строках.
Что дальше?
Изучите другие Kotlin-идиомы.
Узнайте, как преобразовать существующий Java-код в Kotlin с помощью конвертера Java в Kotlin.
Если у вас есть любимая идиома, мы приглашаем вас поделиться ею, отправив запрос на добавление.
© 2010–2022 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/java-to-kotlin-idioms-strings.html