0

[Java Backend Zero to Hello] BÀI 1.4: MẢNG & STRING

Java Backend Zero to Hello

📚 Bài viết thuộc series Java Backend Zero to Hello 📌 Phần: Phase 1: Java Core Cơ Bản | Bài 6/86


BÀI 1.4: MẢNG & STRING

Mục tiêu

  • Khai báo và sử dụng mảng 1 chiều, 2 chiều
  • Thao tác với String và StringBuilder
  • Hiểu String Pool và tính bất biến (immutable)

1. MẢNG (ARRAY)

Mảng là tập hợp các phần tử cùng kiểu, có kích thước cố định.

1.1 Khai báo mảng

// Cách 1: Khai báo rồi khởi tạo
int[] numbers = new int[5];  // Mảng 5 phần tử, mặc định = 0

// Cách 2: Khai báo và gán giá trị
int[] scores = {10, 20, 30, 40, 50};

// Cách 3: Khai báo trước, khởi tạo sau
String[] names;
names = new String[]{"An", "Bình", "Châu"};

1.2 Truy cập phần tử

int[] arr = {10, 20, 30, 40, 50};
System.out.println(arr[0]);   // 10 - phần tử đầu
System.out.println(arr[4]);   // 50 - phần tử cuối
System.out.println(arr.length);  // 5 - độ dài mảng

arr[2] = 99;  // Gán lại giá trị

1.3 Duyệt mảng

int[] arr = {10, 20, 30, 40, 50};

// Cách 1: For thường
for (int i = 0; i < arr.length; i++) {
    System.out.println(arr[i]);
}

// Cách 2: For-each
for (int num : arr) {
    System.out.println(num);
}

1.4 Mảng 2 chiều

// Ma trận 3x3
int[][] matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

System.out.println(matrix[0][0]);  // 1
System.out.println(matrix[1][2]);  // 6
System.out.println(matrix.length); // 3 (số hàng)

// Duyệt ma trận
for (int i = 0; i < matrix.length; i++) {
    for (int j = 0; j < matrix[i].length; j++) {
        System.out.print(matrix[i][j] + " ");
    }
    System.out.println();
}

1.5 Các thao tác thường gặp

import java.util.Arrays;

int[] arr = {5, 2, 8, 1, 9};

// Sắp xếp
Arrays.sort(arr);  // [1, 2, 5, 8, 9]

// Tìm kiếm nhị phân (mảng phải đã sắp xếp)
int index = Arrays.binarySearch(arr, 5);  // 2

// Chuyển mảng thành chuỗi
System.out.println(Arrays.toString(arr));  // [1, 2, 5, 8, 9]

// Sao chép mảng
int[] copy = Arrays.copyOf(arr, arr.length);
int[] range = Arrays.copyOfRange(arr, 1, 4);  // [2, 5, 8]

// Điền giá trị
int[] filled = new int[5];
Arrays.fill(filled, 10);  // [10, 10, 10, 10, 10]

// So sánh mảng
boolean equal = Arrays.equals(arr, copy);  // true

2. STRING

2.1 Khai báo String

String s1 = "Hello";              // String literal (dùng String Pool)
String s2 = new String("Hello");  // Tạo mới trong Heap
String s3 = "Hello";              // Trỏ về cùng object trong Pool

2.2 String Pool

String a = "Java";
String b = "Java";
System.out.println(a == b);       // true (cùng tham chiếu trong Pool)

String c = new String("Java");
System.out.println(a == c);       // false (khác tham chiếu)
System.out.println(a.equals(c));  // true (cùng giá trị)

💡 Best practice: Luôn dùng .equals() để so sánh nội dung String, không dùng ==.

2.3 Các phương thức quan trọng

Lấy thông tin

String s = "Hello World";
s.length();              // 11
s.charAt(0);             // 'H'
s.indexOf("World");      // 6
s.lastIndexOf("o");      // 7
s.isEmpty();             // false
s.isBlank();             // false (Java 11+)

So sánh

String a = "Hello";
String b = "hello";
a.equals(b);             // false (phân biệt hoa thường)
a.equalsIgnoreCase(b);   // true
a.compareTo(b);          // -32 (theo thứ tự từ điển)

Cắt & Nối

String s = "Hello World";
s.substring(0, 5);       // "Hello"
s.substring(6);          // "World"
s.concat("!");           // "Hello World!"
String.join("-", "2024", "01", "15");  // "2024-01-15"

Thay thế & Tách

String s = "Hello World";
s.replace("World", "Java");  // "Hello Java"
s.replaceAll("\\s", "_");    // "Hello_World" (regex)
s.toLowerCase();             // "hello world"
s.toUpperCase();             // "HELLO WORLD"
s.trim();                    // Bỏ khoảng trắng 2 đầu
s.strip();                   // Bỏ khoảng trắng (Unicode, Java 11+)

String csv = "a,b,c,d";
csv.split(",");              // ["a", "b", "c", "d"]

Kiểm tra

String s = "Hello World";
s.startsWith("Hello");   // true
s.endsWith("World");     // true
s.contains("lo Wo");     // true
s.matches(".*World");    // true (regex)

2.4 String là Immutable (Bất biến)

String s = "Hello";
s.concat(" World");  // Tạo String mới, s không đổi
System.out.println(s);  // "Hello"

s = s.concat(" World");  // Gán lại tham chiếu
System.out.println(s);  // "Hello World"

Mỗi lần "thay đổi" String thực chất tạo object mới → Tốn bộ nhớ nếu thao tác nhiều.


3. STRINGBUILDER & STRINGBUFFER

Dùng khi cần thay đổi chuỗi nhiều lần (hiệu quả hơn String).

3.1 StringBuilder (không đồng bộ - nhanh hơn)

StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
sb.append("!");
System.out.println(sb.toString());  // "Hello World!"

// Khởi tạo với giá trị
StringBuilder sb2 = new StringBuilder("Hello");
sb2.append(" World");

// Chèn, xóa, đảo
sb2.insert(5, ",");          // "Hello, World"
sb2.delete(5, 6);            // "Hello World"
sb2.reverse();               // "dlroW olleH"
sb2.replace(0, 5, "Hi");     // "Hi World"

3.2 StringBuffer (đồng bộ - thread-safe)

StringBuffer sbf = new StringBuffer("Hello");
sbf.append(" World");
// API giống StringBuilder

3.3 So sánh hiệu năng

// ❌ Chậm - tạo nhiều object
String result = "";
for (int i = 0; i < 1000; i++) {
    result += i;
}

// ✅ Nhanh - dùng StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i);
}
String result = sb.toString();

4. TEXT BLOCK (Java 13+)

String html = """
        <html>
            <body>
                <h1>Hello World</h1>
            </body>
        </html>
        """;

String json = """
        {
            "name": "Java",
            "version": 17
        }
        """;

5. BÀI TẬP THỰC HÀNH

Bài 1: Tìm phần tử lớn nhất/nhỏ nhất

public static int findMax(int[] arr) {
    int max = arr[0];
    for (int num : arr) {
        if (num > max) max = num;
    }
    return max;
}

Bài 2: Đảo ngược mảng

public static void reverse(int[] arr) {
    int left = 0, right = arr.length - 1;
    while (left < right) {
        int temp = arr[left];
        arr[left] = arr[right];
        arr[right] = temp;
        left++;
        right--;
    }
}

Bài 3: Đếm số lần xuất hiện của ký tự

public static Map<Character, Integer> countChars(String s) {
    Map<Character, Integer> map = new HashMap<>();
    for (char c : s.toCharArray()) {
        map.put(c, map.getOrDefault(c, 0) + 1);
    }
    return map;
}

Bài 4: Kiểm tra chuỗi đối xứng (Palindrome)

public static boolean isPalindrome(String s) {
    s = s.replaceAll("\\s+", "").toLowerCase();
    int left = 0, right = s.length() - 1;
    while (left < right) {
        if (s.charAt(left) != s.charAt(right)) return false;
        left++;
        right--;
    }
    return true;
}

Bài 5: Tính tổng đường chéo ma trận vuông

Bài 6: Chuyển CSV thành mảng 2 chiều


6. TÓM TẮT

Khái niệm Điểm chính
Mảng 1D int[] arr = new int[n];
Mảng 2D int[][] matrix = new int[m][n];
length Thuộc tính độ dài mảng
String Pool String literal được lưu trong Pool
equals() So sánh nội dung String
== So sánh tham chiếu
StringBuilder Thay đổi chuỗi hiệu quả
Immutable String không thể thay đổi

Bài tiếp theo: 1.5 Phương thức & Tái sử dụng code


🧭 Điều Hướng Series

⬅️ Bài trước: BÀI 1.3: CẤU TRÚC ĐIỀU KHIỂN

📋 Lộ trình tổng quan: Xem Toàn Bộ Series

➡️ Bài tiếp theo: BÀI 1.5: PHƯƠNG THỨC & TÁI SỬ DỤNG CODE


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí