Chuyển tới nội dung chính

ArrayList trong Java

ArrayList là một lớp trong Java Collections Framework, cung cấp một cấu trúc dữ liệu động có thể mở rộng kích thước tự động. ArrayList lưu trữ các phần tử trong một mảng động và tự động điều chỉnh kích thước khi cần thiết.

1. Khai báo và khởi tạo ArrayList

Khai báo ArrayList

// Khai báo ArrayList kiểu Integer
ArrayList<Integer> numbers;

// Khai báo ArrayList kiểu String
ArrayList<String> names;

// Khai báo ArrayList kiểu Object
ArrayList<Object> objects;

Khởi tạo ArrayList

// Khởi tạo ArrayList rỗng
ArrayList<Integer> numbers = new ArrayList<>();

// Khởi tạo ArrayList với kích thước ban đầu
ArrayList<String> names = new ArrayList<>(10);

// Khởi tạo ArrayList từ Collection khác
List<Integer> list = Arrays.asList(1, 2, 3);
ArrayList<Integer> numbers = new ArrayList<>(list);

2. Các phương thức cơ bản

Thêm phần tử

ArrayList<String> names = new ArrayList<>();

// Thêm một phần tử vào cuối danh sách
names.add("John");

// Thêm một phần tử vào vị trí chỉ định
names.add(0, "Alice");

// Thêm nhiều phần tử từ một Collection
names.addAll(Arrays.asList("Bob", "Charlie"));

Xóa phần tử

ArrayList<String> names = new ArrayList<>();
names.add("John");
names.add("Alice");
names.add("Bob");

// Xóa phần tử theo giá trị
names.remove("John");

// Xóa phần tử theo vị trí
names.remove(0);

// Xóa tất cả phần tử
names.clear();

// Xóa các phần tử theo điều kiện
names.removeIf(name -> name.startsWith("A"));

Truy cập phần tử

ArrayList<String> names = new ArrayList<>();
names.add("John");
names.add("Alice");

// Lấy phần tử theo vị trí
String first = names.get(0);

// Thay đổi phần tử tại vị trí
names.set(0, "Johnny");

// Kiểm tra phần tử tồn tại
boolean exists = names.contains("Alice");

// Tìm vị trí của phần tử
int index = names.indexOf("Alice");

3. Các phương thức tiện ích

Kích thước và kiểm tra

ArrayList<String> names = new ArrayList<>();

// Lấy kích thước của ArrayList
int size = names.size();

// Kiểm tra ArrayList rỗng
boolean isEmpty = names.isEmpty();

// Đảm bảo dung lượng tối thiểu
names.ensureCapacity(100);

Chuyển đổi

ArrayList<String> names = new ArrayList<>();
names.add("John");
names.add("Alice");

// Chuyển ArrayList thành mảng
String[] array = names.toArray(new String[0]);

// Chuyển ArrayList thành List
List<String> list = names.subList(0, names.size());

Sắp xếp

ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(5);
numbers.add(2);
numbers.add(8);

// Sắp xếp tăng dần
Collections.sort(numbers);

// Sắp xếp giảm dần
Collections.sort(numbers, Collections.reverseOrder());

4. Duyệt ArrayList

Sử dụng vòng lặp for

ArrayList<String> names = new ArrayList<>();
names.add("John");
names.add("Alice");

// Duyệt theo chỉ số
for (int i = 0; i < names.size(); i++) {
System.out.println(names.get(i));
}

// Duyệt theo phần tử
for (String name : names) {
System.out.println(name);
}

Sử dụng Iterator

ArrayList<String> names = new ArrayList<>();
names.add("John");
names.add("Alice");

// Sử dụng Iterator
Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
String name = iterator.next();
System.out.println(name);
}

// Sử dụng ListIterator
ListIterator<String> listIterator = names.listIterator();
while (listIterator.hasNext()) {
String name = listIterator.next();
System.out.println(name);
}

5. Ví dụ thực tế

Quản lý danh sách sản phẩm

public class ProductManager {
private ArrayList<Product> products;

public ProductManager() {
products = new ArrayList<>();
}

public void addProduct(Product product) {
products.add(product);
}

public void removeProduct(String productId) {
products.removeIf(p -> p.getId().equals(productId));
}

public Product findProduct(String productId) {
return products.stream()
.filter(p -> p.getId().equals(productId))
.findFirst()
.orElse(null);
}

public void sortByPrice() {
Collections.sort(products, (p1, p2) ->
Double.compare(p1.getPrice(), p2.getPrice()));
}
}

Quản lý danh sách học sinh

public class StudentManager {
private ArrayList<Student> students;

public StudentManager() {
students = new ArrayList<>();
}

public void addStudent(Student student) {
students.add(student);
}

public ArrayList<Student> getStudentsByGrade(double grade) {
ArrayList<Student> result = new ArrayList<>();
for (Student student : students) {
if (student.getGrade() >= grade) {
result.add(student);
}
}
return result;
}

public double getAverageGrade() {
return students.stream()
.mapToDouble(Student::getGrade)
.average()
.orElse(0.0);
}
}

6. Best Practices

  1. Chỉ định kiểu dữ liệu khi khai báo

    // Không nên
    ArrayList list = new ArrayList();

    // Nên
    ArrayList<String> list = new ArrayList<>();
  2. Sử dụng ensureCapacity khi biết trước kích thước

    // Không nên
    ArrayList<String> names = new ArrayList<>();
    for (int i = 0; i < 1000; i++) {
    names.add("Name " + i);
    }

    // Nên
    ArrayList<String> names = new ArrayList<>();
    names.ensureCapacity(1000);
    for (int i = 0; i < 1000; i++) {
    names.add("Name " + i);
    }
  3. Sử dụng removeIf thay vì Iterator để xóa theo điều kiện

    // Không nên
    Iterator<String> iterator = names.iterator();
    while (iterator.hasNext()) {
    if (iterator.next().startsWith("A")) {
    iterator.remove();
    }
    }

    // Nên
    names.removeIf(name -> name.startsWith("A"));

7. Lỗi thường gặp

  1. IndexOutOfBoundsException

    ArrayList<String> names = new ArrayList<>();
    names.get(0); // Lỗi: ArrayList rỗng
  2. ConcurrentModificationException

    ArrayList<String> names = new ArrayList<>();
    names.add("John");

    for (String name : names) {
    names.remove(name); // Lỗi: sửa đổi trong khi duyệt
    }
  3. NullPointerException

    ArrayList<String> names = null;
    names.add("John"); // Lỗi: ArrayList chưa được khởi tạo