Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Поиск и возвращение строк в Java: полный разбор
Вопрос немного неточный (не указана конкретная строка), но расскажу о самых популярных операциях поиска и возврата строк, которые часто спрашивают на собеседованиях.
1. Поиск подстроки: contains() и indexOf()
contains() — проверка наличия
String text = "Hello World";
// Проверить, содержится ли подстрока
boolean hasWorld = text.contains("World"); // true
boolean hasJava = text.contains("Java"); // false
// Внутренно: contains использует indexOf
public boolean contains(CharSequence s) {
return indexOf(s.toString()) >= 0; // >= 0 означает найдена
}
indexOf() — найти позицию
String text = "Hello World";
// Найти позицию первого вхождения
int pos1 = text.indexOf("o"); // 4 (первый o в "Hello")
int pos2 = text.indexOf("o", 5); // 7 (второй o в "World", начиная с позиции 5)
int pos3 = text.indexOf("Java"); // -1 (не найдена)
// Если не найдена, вернется -1
if (text.indexOf("World") != -1) {
System.out.println("World найдена");
}
lastIndexOf() — найти последнее вхождение
String text = "Hello World Hello";
int pos = text.lastIndexOf("Hello"); // 12 (последний "Hello")
int pos2 = text.lastIndexOf("o"); // 16 (последний o)
2. Получение подстроки: substring()
String text = "Hello World";
// substring(начало, конец) — получить часть строки
// ВАЖНО: конец исключается!
String part1 = text.substring(0, 5); // "Hello" (0-4)
String part2 = text.substring(6); // "World" (от 6 до конца)
String part3 = text.substring(0); // "Hello World" (от 0 до конца)
// Вот где ошибаются многие:
String text2 = "Java";
String result = text2.substring(0, 4); // "Java" (0,1,2,3 индексы)
try {
String wrong = text2.substring(0, 5); // Индекс 5 не существует!
} catch (StringIndexOutOfBoundsException e) {
System.out.println("Ошибка: выходит за границы строки");
}
3. Регулярные выражения: matches() и replaceAll()
matches() — проверить по паттерну
String email = "user@example.com";
// Проверить по regex
boolean isEmail = email.matches("[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}");
// true
String phone = "123-456-7890";
boolean isPhone = phone.matches("\\d{3}-\\d{3}-\\d{4}");
// true
// ВАЖНО: matches проверяет ВСЮ строку
String text = "Hello 123 World";
boolean has123 = text.matches(".*123.*"); // true (точки означают любой символ)
boolean is123 = text.matches("123"); // false (не вся строка это "123")
replaceAll() — заменить по паттерну
String text = "Hello 123 World 456";
// Заменить все цифры на X
String result = text.replaceAll("\\d", "X"); // "Hello XXX World XXX"
// Заменить слова на другие
String text2 = "cat cat cat";
String result2 = text2.replaceAll("cat", "dog"); // "dog dog dog"
// Заменить с группами
String date = "12-25-2024";
String formatted = date.replaceAll("(\\d+)-(\\d+)-(\\d+)", "$3/$2/$1");
// "2024/25/12" (переставили группы)
4. Разделение и объединение
split() — разделить на массив
String csv = "John,Jane,Bob,Alice";
// Разделить по запятой
String[] names = csv.split(","); // ["John", "Jane", "Bob", "Alice"]
String first = names[0]; // "John"
// split с regex
String words = "Hello-World-Java";
String[] parts = words.split("-"); // ["Hello", "World", "Java"]
// split с лимитом
String text = "a:b:c:d:e";
String[] limited = text.split(":", 3); // ["a", "b", "c:d:e"]
join() — объединить (Java 8+)
String[] names = {"John", "Jane", "Bob"};
// Объединить с разделителем
String result = String.join(", ", names); // "John, Jane, Bob"
// С коллекцией
List<String> items = List.of("apple", "banana", "orange");
String joined = String.join("-", items); // "apple-banana-orange"
5. Поиск в коллекциях: stream().filter()
Найти элемент в списке
List<String> fruits = List.of("apple", "banana", "cherry");
// Проверить, есть ли элемент
boolean hasApple = fruits.contains("apple"); // true
// Найти первый элемент по условию (Java 8+)
Optional<String> found = fruits.stream()
.filter(f -> f.startsWith("b"))
.findFirst();
if (found.isPresent()) {
System.out.println("Найдено: " + found.get()); // "banana"
} else {
System.out.println("Не найдено");
}
// Или через orElse
String result = fruits.stream()
.filter(f -> f.contains("a"))
.findFirst()
.orElse("не найдено"); // "apple"
6. Обработка символов
charAt() — получить символ по индексу
String text = "Java";
char first = text.charAt(0); // J
char last = text.charAt(3); // a
try {
char wrong = text.charAt(10); // IndexOutOfBoundsException
} catch (StringIndexOutOfBoundsException e) {
System.out.println("Индекс вне границ");
}
// Часто используют в циклах
for (int i = 0; i < text.length(); i++) {
System.out.println(text.charAt(i));
}
toCharArray() — преобразовать в массив
String text = "Hello";
char[] chars = text.toCharArray(); // [H, e, l, l, o]
// Можно менять
chars[0] = J;
String modified = new String(chars); // "Jello"
7. Практические примеры: разные задачи
Задача 1: Найти все гласные в строке
public List<Character> findVowels(String text) {
String vowels = "aeiouAEIOU";
List<Character> result = new ArrayList<>();
for (char c : text.toCharArray()) {
if (vowels.indexOf(c) >= 0) { // или contains
result.add(c);
}
}
return result;
}
// Использование
List<Character> vowels = findVowels("Hello World");
// [e, o, o]
Задача 2: Проверить, является ли строка палиндромом
public boolean isPalindrome(String text) {
String clean = text.toLowerCase().replaceAll("[^a-z0-9]", "");
String reversed = new StringBuilder(clean).reverse().toString();
return clean.equals(reversed);
}
// Использование
System.out.println(isPalindrome("A man, a plan, a canal, Panama")); // true
System.out.println(isPalindrome("Hello")); // false
Задача 3: Подсчитать количество вхождений подстроки
public int countOccurrences(String text, String substring) {
int count = 0;
int index = 0;
while ((index = text.indexOf(substring, index)) != -1) {
count++;
index += substring.length();
}
return count;
}
// Использование
int count = countOccurrences("ababab", "ab"); // 3
// Или через regex
int regexCount = text.split("ab", -1).length - 1; // -1 сохраняет пустые строки
Задача 4: Найти первое слово в строке
public String getFirstWord(String text) {
if (text == null || text.isEmpty()) {
return null;
}
int spaceIndex = text.indexOf(" ");
if (spaceIndex == -1) {
return text; // нет пробелов
}
return text.substring(0, spaceIndex);
}
// Использование
String word = getFirstWord("Hello World Java"); // "Hello"
8. Важные моменты про String
String immutability
String text = "Hello";
String result = text.substring(0, 3); // Создается НОВАЯ строка "Hel"
// text остается "Hello"
// Это значит:
String a = "Hello";
String b = a.toLowerCase(); // b это новая строка
// a это еще "Hello", не "hello"
Кэширование строк (String pool)
String a = "Hello"; // в String pool
String b = "Hello"; // указывает на ту же ячейку памяти
String c = new String("Hello"); // новая ячейка памяти
System.out.println(a == b); // true (указывают на одно место)
System.out.println(a == c); // false (разные места в памяти)
System.out.println(a.equals(c)); // true (содержание одинаковое)
На собеседовании
"Java имеет множество методов для работы со строками. Основные:
- contains/indexOf — поиск подстроки
- substring — извлечение части строки (будь осторожен с индексами)
- matches/replaceAll — regex для сложных паттернов
- split/join — разделение и объединение
- stream().filter() — поиск в коллекциях
И помни: все String методы возвращают новую строку, потому что String immutable."
Вывод
Методы работы со строками — это основа Java. Важно понимать:
- indexOf возвращает -1, если не найдена
- substring(a, b) исключает конец (b не включается)
- Все методы возвращают новую строку, старая не меняется
- regex мощный инструмент, но дорогой по CPU
- Stream API удобен для поиска в коллекциях