0

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

📚 Series: Java Backend Zero to Hello 📂 Phân đoạn: Phase 1: Java Core cơ bản 📖 Nội dung: BÀI 1.4: MẢNG & STRING 💡 Khóa học lập trình Backend Java & Spring Boot chuẩn doanh nghiệp từ con số 0.


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 bài học

⭐ Hãy bookmark (clip) lại series để tiện theo dõi các bài học tiếp theo nhé!


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í