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
-
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<>(); -
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);
} -
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
-
IndexOutOfBoundsException
ArrayList<String> names = new ArrayList<>();
names.get(0); // Lỗi: ArrayList rỗng -
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
} -
NullPointerException
ArrayList<String> names = null;
names.add("John"); // Lỗi: ArrayList chưa được khởi tạo