W3docs

Строки в Java

Работа с объектами String в Java — создание, конкатенация и обработка строк, а также понимание неизменяемости строк.

String представляет собой последовательность символов и, после int, является типом, с которым вы будете работать чаще всего. Это класс (не примитив), но Java предоставляет ему специальный синтаксис — литералы в двойных кавычках, оператор + для конкатенации — поэтому в использовании он похож на примитив. Самый важный факт о строках: они неизменяемы.

В этой главе рассматривается, как создавать строки, почему неизменяемость важна, как измерять и индексировать строки, как правильно сравнивать их, повседневные методы, конкатенация, многострочные текстовые блоки и форматирование.

Создание строки

Самый простой способ — строковый литерал в двойных кавычках:

String greeting = "Hello, World!";
String empty = "";
String multi = "Line 1\nLine 2";   // \n is a newline

Можно также создать строку с помощью new, хотя для этого редко возникает причина:

String fromLiteral = "Hello";
String fromNew = new String("Hello");

new String(...) всегда выделяет новый объект. Литералы помещаются в пул — два литерала с одинаковыми символами являются одним и тем же объектом. Это важно для сравнений с ==, но не во всём остальном; для сравнения содержимого всегда следует использовать .equals().

Строки неизменяемы

После создания String её содержимое никогда не изменяется. Каждый метод, который «изменяет» строку, на самом деле возвращает новую строку:

String s = "hello";
s.toUpperCase();
System.out.println(s);   // "hello" — unchanged

s = s.toUpperCase();
System.out.println(s);   // "HELLO" — new string assigned

Неизменяемость имеет несколько преимуществ:

  • Безопасно использовать между потоками — синхронизация не нужна.
  • Хеш-код может быть кэширован.
  • Строки можно безопасно использовать в качестве ключей в коллекциях.

Компромисс: построение длинной строки в цикле с помощью + создаёт множество промежуточных строк. Для этого используйте StringBuilder (конкатенация строк).

Длина и индексация

length() возвращает количество символов:

String s = "hello";
System.out.println(s.length());   // 5

charAt(i) возвращает символ по индексу i (отсчёт с нуля):

System.out.println(s.charAt(0));   // 'h'
System.out.println(s.charAt(4));   // 'o'
// s.charAt(5);  // StringIndexOutOfBoundsException

Примечание: length() возвращает количество UTF-16 кодовых единиц, а не всегда количество воспринимаемых пользователем символов. Для большинства ASCII и BMP-текста они совпадают, но эмодзи и некоторые нелатинские символы используют суррогатные пары и считаются как 2.

Сравнение строк

Для сравнения содержимого используйте .equals(), а не ==:

String a = new String("hi");
String b = new String("hi");

System.out.println(a == b);         // false
System.out.println(a.equals(b));    // true

equalsIgnoreCase игнорирует регистр:

"HELLO".equalsIgnoreCase("hello");  // true

Для упорядочивания используйте compareTo. Он сравнивает строки лексикографически (по коду символа) и возвращает отрицательное число, если первая строка стоит перед второй, 0 при равенстве и положительное число, если первая стоит после:

"apple".compareTo("banana");        // negative (a < b)
"apple".compareTo("apple");         // 0  — equal
"banana".compareTo("apple");        // positive (b > a)

Поскольку сравнение производится по коду символа, заглавные буквы (AZ, коды 65–90) идут раньше строчных (az, коды 97–122). Для регистронезависимого упорядочивания используйте compareToIgnoreCase.

Основные операции

Наиболее часто используемые методы с примерами:

String s = "  Hello, World!  ";

s.length();                  // 17
s.trim();                    // "Hello, World!" (whitespace removed)
s.strip();                   // "Hello, World!" (Unicode-aware, Java 11+)
s.toUpperCase();             // "  HELLO, WORLD!  "
s.toLowerCase();             // "  hello, world!  "
s.contains("World");         // true
s.startsWith("  Hello");     // true
s.endsWith("!  ");           // true
s.indexOf("World");          // 9
s.indexOf("xyz");            // -1
s.replace(",", ";");         // "  Hello; World!  "
s.substring(2, 7);           // "Hello"
s.split(", ");               // ["  Hello", "World!  "]
s.isEmpty();                 // false  — length() == 0?
s.isBlank();                 // false  — only whitespace? (Java 11+)

Полный справочник см. в методах строк Java.

Конкатенация

Оператор + объединяет строки и при необходимости преобразует другие типы в строку:

String name = "Ada";
int age = 36;
String msg = "Name: " + name + ", Age: " + age;
// "Name: Ada, Age: 36"

Внутри цикла предпочтительнее использовать StringBuilder:

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
    sb.append(i).append(",");
}
String result = sb.toString();

Текстовые блоки — многострочные строки

Начиная с Java 15, текстовые блоки позволяют писать многострочные строки без экранирования:

String json = """
        {
          "name": "Ada",
          "age": 36
        }
        """;

Компилятор удаляет общий ведущий пробел из каждой строки, поэтому отступы в исходном коде не попадают в строку.

Форматирование

String.format создаёт строку с заполнителями в стиле printf:

String s = String.format("Name: %s, Age: %d", "Ada", 36);

Заполнители те же, что и в System.out.printf — см. вывод в Java.

Демонстрация

java— editable, runs on the server

Что дальше

Методы строк Java — справочник всех методов, которые вы будете регулярно использовать.

Практика

Практика
Какое утверждение о строках в Java является верным?
Какое утверждение о строках в Java является верным?
Was this page helpful?