Khi thực hiện xóa phần tử khỏi danh sách trong quá trình lặp, nhiều vấn đề phát sinh có thể khiến kết quả không như mong đợi. Dưới đây là một số tình huống phổ biến và cách xử lý:
- Sử dụng độ dài cố định gây lỗi IndexOutOfBoundsException
DanhSach<String> danhSach = new ArrayList<>();
danhSach.them("x");
danhSach.them("y");
danhSach.them("z");
danhSach.them("w");
danhSach.them("v");
System.out.println("Trước khi xóa: " + danhSach.toString());
int soPhanTu = danhSach.kichThuoc();
for (int viTri = 0; viTri < soPhanTu; viTri++) {
if ("z".equals(danhSach.lay(viTri))) {
danhSach.xoa(viTri);
}
}
System.out.println("Sau khi xóa: " + danhSach.toString());
Lỗi xảy ra khi xóa phần tử làm thay đổi kích thước danh sách, dẫn đến truy cập vị trí ngoài phạm vi.
- Lấy độ dài động gây bỏ sót phần tử
DanhSach<String> danhSach = new ArrayList<>();
danhSach.them("m");
danhSach.them("n");
danhSach.them("o");
danhSach.them("p");
danhSach.them("q");
danhSach.them("r");
System.out.println("Trước khi xóa: " + danhSach.toString());
for (int viTri = 0; viTri < danhSach.kichThuoc(); viTri++) {
if ("o".equals(danhSach.lay(viTri)) || "p".equals(danhSach.lay(viTri))) {
danhSach.xoa(viTri);
}
}
System.out.println("Sau khi xóa: " + danhSach.toString());
Khi xóa phần tử "o" tại vị trí 2, phần tử "p" sẽ dịch chuyển lên vị trí 2, nhưng vòng lặp tiếp tục từ vị trí 3, dẫn đến bỏ sót phần tử.
- Sử dụng foreach gây ConcurrentModificationException
DanhSach<String> danhSach = new ArrayList<>();
danhSach.them("s");
danhSach.them("t");
danhSach.them("u");
danhSach.them("v");
danhSach.them("w");
danhSach.them("x");
System.out.println("Trước khi xóa: " + danhSach.toString());
for (String phanTu : danhSach) {
if ("u".equals(phanTu)) {
danhSach.xoa(phanTu);
}
}
System.out.println("Sau khi xóa: " + danhSach.toString());
Lỗi xảy ra do sự không khớp giữa biến đếm sửa đổi (modCount) và giá trị kỳ vọng (expectedModCount) khi thay đổi danh sách trong quá trình lặp.
- Phương pháp đúng: Sử dụng Iterator
DanhSach<String> danhSach = new ArrayList<>();
danhSach.them("a");
danhSach.them("b");
danhSach.them("c");
danhSach.them("d");
danhSach.them("e");
danhSach.them("f");
System.out.println("Trước khi xóa: " + danhSach.toString());
Iterator<String> lap = danhSach.iterator();
while (lap.hasNext()) {
String giaTri = lap.next();
if ("c".equals(giaTri)) {
lap.xoa();
}
}
System.out.println("Sau khi xóa: " + danhSach.toString());
Phương pháp này đảm bảo danh sách được cập nhật đúng cách trong quá trình lặp mà không gây lỗi.