Bài 7: List Interface và ArrayList

1. Giới thiệu List Interface và ArrayList

a) List Interface


b) ArrayList class

Ví dụ:

import java.util.ArrayList;
import java.util.List;

public class DemoArrayList {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        // Thêm phần tử
        list.add("Java");
        list.add("C++");
        list.add("Python");

        // In danh sách
        System.out.println("Danh sách: " + list);

        // Lấy phần tử
        System.out.println("Phần tử đầu tiên: " + list.get(0));

        // Sửa phần tử
        #list.set(1, "C#");
        System.out.println("Sau khi sửa: " + list);

        // Xóa phần tử
        list.remove("Python");
        System.out.println("Sau khi xóa: " + list);

        // Duyệt bằng for-each
        for (String lang : list) {
            System.out.println(lang);
        }
    }
}

2. 🔎 So sánh Mảng (Array)List (ArrayList)

Tiêu chí Mảng (Array) List (ArrayList)
Kích thước Cố định, không thay đổi sau khi khai báo. Linh hoạt, có thể tự động tăng/giảm kích thước khi thêm/xóa phần tử.
Khai báo int[] a = new int[5]; List<Integer> list = new ArrayList<>();
Kiểu dữ liệu Chỉ chứa cùng kiểu dữ liệu đã khai báo. Có thể chứa đối tượng (class), hỗ trợ Generics (List<String>, List<Integer>, …).
Cú pháp truy cập Dùng chỉ số: a[0]. Dùng phương thức: list.get(0).
Thêm phần tử Phải gán trực tiếp: a[0] = 5;. Dùng list.add(5);.
Xóa phần tử Không có sẵn, phải viết code dịch chuyển thủ công. Dùng list.remove(index) hoặc list.remove(Object).
Tìm kiếm Tự viết vòng lặp. Có sẵn contains(), indexOf(), …
Sắp xếp Dùng Arrays.sort(). Dùng Collections.sort().
Hiệu năng Nhanh hơn vì là cấu trúc cơ bản, ít overhead. Chậm hơn chút do có nhiều phương thức tiện ích, nhưng rất linh hoạt.
Ứng dụng Dùng khi biết trước số lượng phần tử và cần hiệu năng cao (VD: xử lý mảng số trong game, toán học). Dùng khi số lượng phần tử thay đổi thường xuyên (VD: danh sách sinh viên, giỏ hàng online).

📝 Ví dụ minh họa

Mảng (Array)

public class DemoArray {
    public static void main(String[] args) {
        int[] arr = new int[3];
        arr[0] = 10;
        arr[1] = 20;
        arr[2] = 30;

        for (int x : arr) {
            System.out.println(x);
        }
    }
}

ArrayList (List)

import java.util.*;

public class DemoList {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(20);
        list.add(30);

        for (int x : list) {
            System.out.println(x);
        }
    }
}

👉 Tóm lại:


3. Bài tập áp dụng ArrayList & List

Bài 1: Nhập và in danh sách số nguyên

import java.util.*;

public class Bai1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        List<Integer> list = new ArrayList<>();

        System.out.print("Nhập số phần tử: ");
        int n = sc.nextInt();

        for (int i = 0; i < n; i++) {
            list.add(sc.nextInt());
        }

        System.out.println("Danh sách vừa nhập: " + list);
        sc.close();
    }
}

Bài 2: Tìm số lớn nhất trong ArrayList

import java.util.*;

public class Bai2 {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(5, 9, 2, 8, 15, 3);
        int max = Collections.max(list);
        System.out.println("Số lớn nhất: " + max);
    }
}

Bài 3: Tính tổng và trung bình cộng

import java.util.*;

public class Bai3 {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
        int sum = 0;
        for (int x : list) sum += x;
        double avg = (double) sum / list.size();
        System.out.println("Tổng = " + sum + ", Trung bình = " + avg);
    }
}

Bài 4: Đếm số chẵn và số lẻ

import java.util.*;

public class Bai4 {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(2, 5, 7, 8, 10, 13);
        int even = 0, odd = 0;
        for (int x : list) {
            if (x % 2 == 0) even++; else odd++;
        }
        System.out.println("Số chẵn: " + even + ", Số lẻ: " + odd);
    }
}

Bài 5: Sắp xếp danh sách tăng dần

import java.util.*;

public class Bai5 {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(Arrays.asList(7, 3, 9, 1, 4));
        Collections.sort(list);
        System.out.println("Sau khi sắp xếp: " + list);
    }
}

Bài 6: Xóa phần tử trùng lặp

import java.util.*;

public class Bai6 {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 2, 3, 4, 4, 5));
        Set<Integer> set = new LinkedHashSet<>(list);
        list = new ArrayList<>(set);
        System.out.println("Danh sách sau khi xóa trùng: " + list);
    }
}

Bài 7: Kiểm tra phần tử có tồn tại trong danh sách

import java.util.*;

public class Bai7 {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("Java", "C++", "Python");
        String key = "Java";
        if (list.contains(key)) {
            System.out.println(key + " có trong danh sách");
        } else {
            System.out.println(key + " không có trong danh sách");
        }
    }
}

Bài 8: Nhập danh sách tên và in ra theo thứ tự A-Z

import java.util.*;

public class Bai8 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        List<String> names = new ArrayList<>();

        System.out.print("Nhập số tên: ");
        int n = sc.nextInt(); sc.nextLine();
        for (int i = 0; i < n; i++) {
            names.add(sc.nextLine());
        }

        Collections.sort(names);
        System.out.println("Danh sách sau khi sắp xếp: " + names);
        sc.close();
    }
}

Bài 9: Quản lý danh sách sinh viên (tên + tuổi)

import java.util.*;

class SinhVien {
    String ten;
    int tuoi;

    SinhVien(String ten, int tuoi) {
        this.ten = ten;
        this.tuoi = tuoi;
    }

    @Override
    public String toString() {
        return ten + " - " + tuoi + " tuổi";
    }
}

public class Bai9 {
    public static void main(String[] args) {
        List<SinhVien> list = new ArrayList<>();
        list.add(new SinhVien("An", 20));
        list.add(new SinhVien("Bình", 22));
        list.add(new SinhVien("Lan", 19));

        for (SinhVien sv : list) {
            System.out.println(sv);
        }
    }
}

Bài 10: Menu quản lý danh sách số nguyên

👉 Cho phép thêm, xóa, tìm, in danh sách.

import java.util.*;

public class Bai10 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        List<Integer> list = new ArrayList<>();
        int choice;

        do {
            System.out.println("\n--- MENU ---");
            System.out.println("1. Thêm số");
            System.out.println("2. Xóa số");
            System.out.println("3. In danh sách");
            System.out.println("4. Tìm số");
            System.out.println("0. Thoát");
            System.out.print("Chọn: ");
            choice = sc.nextInt();

            switch (choice) {
                case 1:
                    System.out.print("Nhập số: ");
                    list.add(sc.nextInt());
                    break;
                case 2:
                    System.out.print("Nhập số cần xóa: ");
                    int x = sc.nextInt();
                    list.remove(Integer.valueOf(x));
                    break;
                case 3:
                    System.out.println("Danh sách: " + list);
                    break;
                case 4:
                    System.out.print("Nhập số cần tìm: ");
                    int y = sc.nextInt();
                    System.out.println(list.contains(y) ? "Tồn tại" : "Không tồn tại");
                    break;
            }
        } while (choice != 0);

        sc.close();
    }
}