Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Ответ
Разворот строки (reversal) — классическая задача, которая часто встречается на интервью и в реальной разработке. Рассмотрю несколько способов от простых к оптимальным.
1. Встроенный метод (самый простой)
public class StringReversal {
public static String reverse(String str) {
return new StringBuilder(str).reverse().toString();
}
public static void main(String[] args) {
String original = "Hello World";
String reversed = reverse(original);
System.out.println(reversed); // dlroW olleH
}
}
Это оптимально для production кода.
2. Цикл в обратном порядке
public class ManualReversal {
public static String reverseWithLoop(String str) {
String reversed = "";
for (int i = str.length() - 1; i >= 0; i--) {
reversed += str.charAt(i);
}
return reversed;
}
public static void main(String[] args) {
String original = "Java";
System.out.println(reverseWithLoop(original)); // avaJ
}
}
Проблема: неэффективно! Каждый += создаёт новую String (immutable).
3. StringBuilder для оптимизации
public class OptimizedReversal {
public static String reverseOptimized(String str) {
StringBuilder sb = new StringBuilder();
for (int i = str.length() - 1; i >= 0; i--) {
sb.append(str.charAt(i));
}
return sb.toString();
}
public static void main(String[] args) {
String original = "Development";
System.out.println(reverseOptimized(original)); // tnempolevеD
}
}
Лучше! StringBuilder переиспользует буфер.
4. Массив символов (самый быстрый)
public class CharArrayReversal {
public static String reverseWithArray(String str) {
char[] chars = str.toCharArray();
// Two-pointer approach
int left = 0, right = chars.length - 1;
while (left < right) {
// Swap
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
return new String(chars);
}
public static void main(String[] args) {
String original = "Programming";
System.out.println(reverseWithArray(original)); // gnimmargorP
}
}
Это оптимально по памяти и скорости.
5. Рекурсия (для интервью)
public class RecursiveReversal {
public static String reverseRecursive(String str) {
// Base case
if (str == null || str.isEmpty()) {
return str;
}
// Recursive case
return reverseRecursive(str.substring(1)) + str.charAt(0);
}
public static void main(String[] args) {
String original = "Recursive";
System.out.println(reverseRecursive(original)); // evisruceR
}
}
Не рекомендуется для production (может быть StackOverflow для больших строк).
6. Stream API (функциональный подход)
import java.util.stream.IntStream;
public class StreamReversal {
public static String reverseWithStream(String str) {
return IntStream.rangeClosed(1, str.length())
.map(i -> str.charAt(str.length() - i))
.collect(
StringBuilder::new,
(sb, c) -> sb.append((char) c),
StringBuilder::append
)
.toString();
}
public static void main(String[] args) {
String original = "Stream";
System.out.println(reverseWithStream(original)); // maertS
}
}
Читаемо, но не самый быстрый способ.
7. Разворот Unicode символов
public class UnicodeReversal {
public static String reverseUnicode(String str) {
// Правильно работает с многобайтными символами
int[] codePoints = str.codePoints().toArray();
// Reverse array
for (int i = 0, j = codePoints.length - 1; i < j; i++, j--) {
int temp = codePoints[i];
codePoints[i] = codePoints[j];
codePoints[j] = temp;
}
return new String(codePoints, 0, codePoints.length);
}
public static void main(String[] args) {
String original = "Hello 世界 🌍";
System.out.println(reverseUnicode(original));
// 🌍 界世 olleH
}
}
8. Разворот слов в строке
public class ReverseWords {
// Развернуть слова, не символы
public static String reverseWords(String str) {
String[] words = str.split(" ");
// Reverse words array
for (int i = 0, j = words.length - 1; i < j; i++, j--) {
String temp = words[i];
words[i] = words[j];
words[j] = temp;
}
return String.join(" ", words);
}
public static void main(String[] args) {
String original = "The quick brown fox";
System.out.println(reverseWords(original));
// fox brown quick The
}
}
9. Разворот с сохранением регистра
public class CasePreservingReversal {
public static String reverseWithCasePreservation(String str) {
char[] reversed = str.toCharArray();
int left = 0, right = reversed.length - 1;
// Развёртываем символы
while (left < right) {
char temp = reversed[left];
reversed[left] = reversed[right];
reversed[right] = temp;
left++;
right--;
}
// Теперь применяем original case
char[] original = str.toCharArray();
for (int i = 0; i < reversed.length; i++) {
if (Character.isUpperCase(original[i])) {
reversed[i] = Character.toUpperCase(reversed[i]);
} else {
reversed[i] = Character.toLowerCase(reversed[i]);
}
}
return new String(reversed);
}
public static void main(String[] args) {
String original = "Hello WORLD";
System.out.println(reverseWithCasePreservation(original));
// DLROW olleH
}
}
10. Тесты для проверки
import static org.junit.jupiter.api.Assertions.*;
public class ReverseStringTest {
@Test
void testBasicReversal() {
assertEquals("dlroW olleH",
reverse("Hello World"));
}
@Test
void testEmptyString() {
assertEquals("", reverse(""));
}
@Test
void testSingleCharacter() {
assertEquals("A", reverse("A"));
}
@Test
void testPalindrome() {
assertEquals("racecar", reverse("racecar"));
}
@Test
void testWithSpecialChars() {
assertEquals("@!#", reverse("#!@"));
}
@Test
void testWithUnicode() {
String emoji = "A😀B";
String reversed = reverse(emoji);
assertTrue(reversed.contains("😀"));
}
private String reverse(String str) {
return new StringBuilder(str).reverse().toString();
}
}
Сравнение производительности
public class PerformanceComparison {
public static void main(String[] args) {
String test = "a".repeat(100000);
// StringBuilder.reverse()
long start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
new StringBuilder(test).reverse().toString();
}
System.out.println("StringBuilder: " +
(System.currentTimeMillis() - start) + "ms");
// Char array
start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
char[] chars = test.toCharArray();
reverseArray(chars);
new String(chars);
}
System.out.println("Char Array: " +
(System.currentTimeMillis() - start) + "ms");
}
private static void reverseArray(char[] chars) {
int left = 0, right = chars.length - 1;
while (left < right) {
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
}
}
Рекомендация
| Сценарий | Метод | Причина |
|---|---|---|
| Production code | StringBuilder.reverse() | Оптимально, читаемо |
| Интервью | Two-pointer + array | Показывает понимание алгоритмов |
| Большие строки | StringBuilder | Эффективно по памяти |
| Unicode strings | codePoints() | Правильно для многобайтных |
| Функциональный стиль | Stream API | Читаемо для функционального |
Лучший выбор для production: new StringBuilder(str).reverse().toString()
Это оптимально, безопасно и читаемо. Встроенная логика StringBuilder уже оптимизирована JVM.