Chuỗi Java immutable – cần tạo chuỗi mới khi đảo ngược.
Cách 1: StringBuffer.reverse() – Dễ nhất, hiệu năng tốt
String original = "Hello World";
String reversed = new StringBuffer(original).reverse().toString();
// "dlroW olleH"
StringBuilder (non-sync) nhanh hơn StringBuffer cho single-thread.
Cách 2: Đệ quy – Đẹp nhưng chậm, risch StackOverflow
public static String reverseRecursive(String str) {
if (str == null || str.isEmpty()) return str;
return reverseRecursive(str.substring(1)) + str.charAt(0);
}
// Tail-recursion (Java không tối ưu TCO, vẫn risk stack overflow)
Cách 3: toCharArray() + swap – Hiểu bản chất, không tạo object trung gian
public static String reverseCharArray(String str) {
if (str == null) return null;
char[] arr = str.toCharArray();
int left = 0, right = arr.length - 1;
while (left < right) {
char tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++; right--;
}
return new String(arr);
}
So sánh hiệu năng (10^6 lần, chuỗi 100 ký tự)
| Phương pháp | Thời gian (ms) | Bộ nhớ | Đề xuất |
|---|---|---|---|
| StringBuilder.reverse() | ~150 | Thấp | ✅ Production |
| StringBuffer.reverse() | ~180 | Thấp | Thread-safe |
| char[] swap | ~120 | Thấp nhất | High-performance |
| Đệ quy | ~2000+ | Cao (stack) | ❌ Chỉ học tập |
Ví dụ benchmark nhanh
public static void main(String[] args) {
String test = "Tutorialspoint".repeat(10); // 140 chars
long start = System.nanoTime();
for (int i = 0; i < 100_000; i++) {
new StringBuilder(test).reverse().toString();
}
System.out.println("StringBuilder: " + (System.nanoTime() - start) / 1e6 + " ms");
}
Kết luận: Dùng new StringBuilder(s).reverse().toString() cho production. Dùng char[] swap nếu cực kỳ nhạy cảm hiệu năng.