2010-08-26 30 views
12

Tôi có một ArrayList, bao gồm một số mục tôi muốn xóa. Tôi có các id của các mục cần xóa được lưu trữ trong danh sách khác. Tìm đoạn mã sau nên làm việc trivially, nhưng đối với một số lý do, phương thức remove() các cuộc gọi được trả lại một giá trị sai:Tại sao lệnh gọi ArrayList.remove (id) của tôi không hoạt động?

ArrayList<Integer> toRemove = new ArrayList<Integer>(); 
    ArrayList<JCheckBox> al = new ArrayList<JCheckBox>(); 

    /* Code that adds a bunch of items to al, and a few integers to toRemove */ 

    System.out.println("Size before removing: " + al.size()); 
    for (int i = toRemove.size() - 1; i >= 0; i--) { 
    System.out.println("Removing id: " + toRemove.get(i) + ": "); 
    System.out.println(al.get(toRemove.get(i))); 
    System.out.println(al.remove(toRemove.get(i))); 
    } 
    System.out.println("Size after removing: " + al.size()); 

Tôi muốn có được nó nếu get() gọi cũng trả lại một giá trị sai, nhưng nó thực sự trả về đối tượng được đề cập. Tôi đang thiếu gì ở đây?

Kết quả của đoạn code trên:

Size before removing: 3 
Removing id: 2: 
javax.swing.JCheckBox[...] 
false 
Size after removing: 3 
+0

Bạn có thể đăng các khai báo chính xác cho 'al' và 'toRemove' không? –

+0

Đã đăng các định nghĩa được yêu cầu. – zigdon

Trả lời

31

tôi đoán là bạn đang gặp một vấn đề với thực tế là remove() bị quá tải với cả intObject, trong khi get() chỉ mất một int. Hãy thử remove(toRemove.get(i).intValue()).

remove(Object) từ AbstractCollection sẽ tìm kiếm thông qua danh sách và loại bỏ các đối tượng nhất định, mà sẽ không có mặt ở đó vì bạn đang gửi nó một Integer và danh sách chỉ có JCheckBox s. Bạn đang cố gắng gọi số remove(int), nhưng vì bạn đang cung cấp số Integer, thay vào đó, quá tải đối tượng được gọi. Bằng cách chuyển đổi Integer thành một số int, bạn tránh được sự cố này

Ngoài ra, bạn luôn có thể chắc chắn Id trong toRemove luôn bằng chỉ mục? Nếu toRemove không phải là lớn nhất để đặt hàng ít nhất, nó sẽ không được.

+0

Cảm ơn - điều đó đã hiệu quả! Và vâng, khi tôi xây dựng toRemove, tôi chắc chắn nó theo thứ tự, để khi tôi đi qua nó theo thứ tự ngược lại, tôi không cần phải điều chỉnh các chỉ mục khi các phần tử được loại bỏ. – zigdon

+0

Câu trả lời này không xem xét các đối tượng 'NULL' – Salman

+0

@Salman Câu hỏi ngụ ý không có' null '. Nếu có một 'null' thì dòng bên trên lệnh' remove() 'sẽ ném một con trỏ null trong khi unboxing đối số cho lệnh gọi' get() 'bên ngoài. – ILMTitan

1

Có hai vấn đề với mã của bạn. Đầu tiên, phương thức "toRemove" sai được gọi. Khi bạn gọi "toRemove.get (i)", giá trị trả về được tự động chuyển thành một java.lang.Integer, thay vì một int. Do đó, java.util.List # remove (Object) được gọi thay vì java.util.List # remove (int). Nó đang cố gắng loại bỏ một đối tượng Integer và trả về false. Nếu bạn truyền Integer đến int, phương thức mong muốn sẽ được gọi.

Vấn đề thứ hai: mỗi khi bạn xóa phần tử của danh sách, chỉ mục của tất cả các phần tử tiếp theo sẽ thay đổi, vì các phần tử đó "bị dịch chuyển" xuống. Có một số cách để giải quyết vấn đề này. Một là sắp xếp danh sách các chỉ mục theo thứ tự giảm dần. Một cách khác là sử dụng một tập các chỉ mục, tạo một mảng mới và sao chép vào mảng mới chỉ những phần tử có chỉ mục không có trong tập hợp.

Các vấn đề liên quan