Урок 7. Строки: String и StringBuilder
Строка — последовательность символов: слово, предложение, целый текст. В Java строки хранит класс String. Строку записывают в двойных кавычках, а одиночный символ (char) — в одинарных: "А" — строка, 'А' — символ.
Основные методы
public class Main {
public static void main(String[] args) {
String s = "Привет, Java";
System.out.println(s.length());
System.out.println(s.charAt(0));
System.out.println(s.toUpperCase());
System.out.println(s.indexOf("Java"));
System.out.println(s.substring(8));
System.out.println(s.substring(0, 6));
System.out.println(s.contains("Java"));
System.out.println(s.replace("Java", "мир"));
}
}12
П
ПРИВЕТ, JAVA
8
Java
Привет
true
Привет, мирСимволы строки нумеруются, как элементы массива, с нуля: в "Привет, Java" буква П имеет номер 0, запятая — 6, пробел — 7, J — 8.
| Метод | Что делает |
|---|---|
length() | длина строки (со скобками, в отличие от массива) |
charAt(i) | символ с номером i |
substring(a) | часть строки с номера a до конца |
substring(a, b) | часть с номера a до b, не включая b |
indexOf(t) | номер первого вхождения t или −1, если его нет |
contains(t) | есть ли t в строке |
startsWith(t), endsWith(t) | начинается или заканчивается ли строка на t |
replace(a, b) | заменяет все a на b |
toUpperCase(), toLowerCase() | все буквы большие или маленькие |
trim() | убирает пробелы по краям |
isEmpty() | строка пустая — длина 0 |
isBlank() | пустая или только из пробелов (с Java 11) |
repeat(n) | строка, повторённая n раз (с Java 11) |
Строки не меняются
Строку в Java нельзя изменить. Методы вроде toUpperCase и replace не трогают исходную строку, а возвращают новую. Если результат никуда не сохранить, он пропадёт:
public class Main {
public static void main(String[] args) {
String name = "anna";
name.toUpperCase();
System.out.println(name);
name = name.toUpperCase();
System.out.println(name);
}
}anna
ANNAПервый вызов создал строку ANNA и тут же её выбросил. Чтобы переменная изменилась, результат нужно присвоить ей.
Обход по символам
public class Main {
public static void main(String[] args) {
String text = "мама мыла раму";
int count = 0;
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == 'а') {
count++;
}
}
System.out.println(count);
}
}4Символы (char) можно сравнивать через == — это просто числа-коды. То же можно записать через for-each: for (char c : text.toCharArray()).
Разбить и склеить
public class Main {
public static void main(String[] args) {
String line = "яблоко,груша,слива";
String[] parts = line.split(",");
System.out.println(parts.length);
System.out.println(parts[1]);
System.out.println(String.join(" + ", parts));
}
}3
груша
яблоко + груша + сливаsplit делит строку по разделителю и возвращает массив, String.join склеивает массив обратно через заданную строку. Разделитель в split — регулярное выражение (шаблон для поиска текста), а в нём некоторые знаки особые: точка, например, значит «любой символ». Поэтому точку пишут так: split("\\."). Слова, между которыми может быть несколько пробелов, разбивают через split("\\s+") — «один или несколько пробельных символов подряд» (перед этим уберите пробелы по краям через trim()).
Сравнение строк
Строки сравнивают методом equals, а не ==:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String answer = in.nextLine();
System.out.println(answer == "yes");
System.out.println(answer.equals("yes"));
System.out.println(answer.equalsIgnoreCase("YES"));
}
}yesfalse
true
true== проверяет, один ли это объект в памяти. Строка, прочитанная с клавиатуры, — новый объект, и == даёт false, хотя текст тот же. equals сравнивает текст, equalsIgnoreCase — текст без учёта больших и маленьких букв. Подробно — в справке Сравнение строк: == и equals.
Для упорядочивания есть a.compareTo(b): отрицательное число, если a идёт раньше b по алфавиту (точнее, по кодам символов), ноль — если строки равны, положительное — если позже.
StringBuilder: когда строку собирают по частям
Каждое s = s + "…" создаёт новую строку и копирует в неё старую. В цикле на тысячи повторов это заметно медленно. Для сборки строки по кусочкам есть StringBuilder — изменяемая строка:
public class Main {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 5; i++) {
sb.append(i).append(' ');
}
String result = sb.toString().trim();
System.out.println(result);
System.out.println(new StringBuilder("Привет").reverse());
}
}1 2 3 4 5
тевирПappend(x)дописывает в конец число, символ или строку и возвращает тот жеStringBuilder, поэтому вызовы можно ставить цепочкой;reverse()переворачивает содержимое;insert(i, x)вставляет в позициюi,deleteCharAt(i)удаляет символ;toString()даёт готовую строкуString.
Частые ошибки
s.lengthбез скобок — у строки это методlength(); у массива, наоборот, полеlengthбез скобок.StringIndexOutOfBoundsException— номер символа за пределами строки:charAt(s.length())илиsubstringс концом больше длины.==вместоequals— сравнение работает «через раз» и ломается на строках из ввода.- Вызов метода у
null— если строке не дали значения,s.length()дастNullPointerException(справка NullPointerException).
Коротко
- Строка —
String, в двойных кавычках; символ —char, в одинарных; номера символов — с нуля. length(),charAt,substring,indexOf,replace,split— основные методы.- Строки не изменяются: методы возвращают новую строку, её нужно сохранить.
- Сравнение —
equalsиequalsIgnoreCase, а не==. - Строку из многих кусочков собирают в
StringBuilder.