← Назад к вопросам

Что знаешь про строки в Java

2.2 Middle🔥 181 комментариев
#Stream API и функциональное программирование#Многопоточность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Строки (String) в Java: полное руководство

Строки — один из наиболее важных типов данных в Java. Класс String представляет последовательность символов и является неизменяемым (immutable) типом данных. Понимание особенностей работы со строками критически важно для написания эффективного кода на Java.

Неизменяемость (Immutability)

Одна из самых важных характеристик String — его неизменяемость. Это значит, что после создания объекта String его содержимое не может быть изменено.

String str = "Hello";
str = str + " World"; // создаёт НОВЫЙ объект String
String str2 = str.toUpperCase(); // создаёт ещё один новый объект

При каждой операции, кажущейся изменением строки, Java создаёт новый объект String. Исходный объект остаётся неизменённым.

String Pool (Пул строк)

Java использует специальный механизм оптимизации памяти — String Pool (пул строк). Это область памяти в heap, где хранятся уникальные строковые литералы:

String s1 = "Hello"; // создаётся новый объект в пуле
String s2 = "Hello"; // ссылается на тот же объект из пула
String s3 = new String("Hello"); // создаёт новый объект в heap за пределами пула

System.out.println(s1 == s2); // true — один и тот же объект
System.out.println(s1 == s3); // false — разные объекты
System.out.println(s1.equals(s3)); // true — одинаковое содержимое

Метод intern() позволяет добавить строку в пул:

String s4 = new String("Hello").intern();
System.out.println(s1 == s4); // true — теперь в одном пуле

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

Важно различать == и equals:

String a = "test";
String b = "test";
String c = new String("test");

System.out.println(a == b); // true — один объект из пула
System.out.println(a == c); // false — разные объекты
System.out.println(a.equals(c)); // true — одинаковое содержимое
System.out.println(a.equalsIgnoreCase("TEST")); // true — игнорирует регистр

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

StringBuilder и StringBuffer

Для построения строк с множественными операциями конкатенации используй StringBuilder (однопоточный) или StringBuffer (потокобезопасный):

// ❌ Неэффективно — создаёт 1000 новых объектов
String result = "";
for (int i = 0; i < 1000; i++) {
    result += i; // каждая итерация создаёт новую String
}

// ✅ Эффективно — использует буфер
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i);
}
String result = sb.toString();

StringBuilder работает быстрее, потому что он mutable — содержимое буфера меняется без создания новых объектов.

Основные методы String

String str = "Hello World";

// Длина и символы
int length = str.length(); // 11
char c = str.charAt(0); // H

// Поиск
int index = str.indexOf("World"); // 6
int lastIndex = str.lastIndexOf("l"); // 9
boolean contains = str.contains("World"); // true

// Подстроки
String substring = str.substring(0, 5); // "Hello"

// Регистр
String upper = str.toUpperCase(); // "HELLO WORLD"
String lower = str.toLowerCase(); // "hello world"

// Разделение и замена
String[] words = str.split(" "); // ["Hello", "World"]
String replaced = str.replace("World", "Java"); // "Hello Java"
String replaceAll = "test123abc".replaceAll("[0-9]", "X"); // "testXXXabc"

// Обрезка
String trimmed = "  hello  ".trim(); // "hello"

// Проверки
boolean startsWith = str.startsWith("Hello"); // true
boolean isEmpty = str.isEmpty(); // false
boolean isBlank = "   ".isBlank(); // true (Java 11+)

Строки и null

String nullable = null;

// Будет NullPointerException
// int len = nullable.length();

// Безопасные проверки
if (nullable != null && !nullable.isEmpty()) {
    // работать со строкой
}

// Java 9+ — использовать Objects.requireNonNull()
import java.util.Objects;
String safe = Objects.requireNonNull(nullable, "Строка не должна быть null");

String Formatting (форматирование)

// String.format()
String formatted = String.format("Hello, %s! You have %d messages", "John", 5);

// printf() (в PrintStream)
System.out.printf("Value: %d, Double: %.2f%n", 42, 3.14159);

// Text blocks (Java 13+)
String json = """
    {
        "name": "John",
        "age": 30
    }
    """;

Шаблонные строки (Java 21+)

String name = "World";
String greeting = STR."Hello, \{name}!"; // "Hello, World!"
int x = 10, y = 20;
String result = STR."\{x} + \{y} = \{x + y}"; // "10 + 20 = 30"

Производительность

// ❌ Медленно в циклах
String result = "";
for (int i = 0; i < 10000; i++) {
    result += getData(i); // O(n²)
}

// ✅ Быстро
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
    sb.append(getData(i));
}
String result = sb.toString(); // O(n)

Ключевые выводы

  • String неизменяем — операции создают новые объекты
  • Используй String Pool для экономии памяти с литералами
  • Различай == (ссылки) и equals() (содержимое)
  • Для конкатенации в циклах используй StringBuilder, не String
  • StringBuffer нужен только для многопоточности
  • Знай основные методы: charAt(), indexOf(), substring(), split(), replace()
  • Для больших текстов и сложного форматирования используй StringBuilder