Xóa mục khỏi ArrayList


100

Tôi có một ArrayListgiả sử list, và nó có 8 mục AH và bây giờ tôi muốn xóa vị trí 1,3,5 Mục được lưu trữ trong mảng int khỏi listlàm thế nào tôi có thể làm điều này.

Tôi đang cố gắng làm điều này với

ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
list.add("F");
list.add("G");
list.add("H");

int i[] = {1,3,5};

for (int j = 0; j < i.length; j++) {
    list.remove(i[j]);
}

Nhưng sau khi mục đầu tiên bị xóa, vị trí của mảng được thay đổi và trong lần lặp tiếp theo, nó sẽ xóa phần tử sai hoặc đưa ra ngoại lệ.


Làm thế nào về việc xóa nó theo thứ tự giảm dần của các chỉ số (sắp xếp các chỉ số, sau đó xóa phần tử có chỉ số cao nhất trước)?
nhahtdh 23/5/12

1
Logic của bạn là thiếu sót. Chắc chắn bạn không nên nghĩ về vị trí của từng món đồ mà thay vào đó hãy nghĩ về bản thân những món đồ đó. Nói cách khác, bạn không muốn để loại bỏ vị trí 1, 3 & 5 nhưng thay vào đó bạn muốn loại bỏ các mục (bất cứ nơi nào họ đang ở List) sử dụng equals("B"), equals("D")equals("F"). Hãy suy nghĩ về nó.
Squonk

Có Tôi muốn xóa Mục nhưng làm thế nào tôi có thể khớp các Mục. Trên thực tế, các mục này nằm trong ListView và khi được chọn, tôi muốn xóa nó khỏi DB và Mảng và làm mới bộ điều hợp và Danh sách
Krishnakant Dalal

Tùy chọn chậm: lặp lại khi thêm các phần tử vào danh sách thứ hai, lặp lại danh sách thứ hai xóa khỏi danh sách đầu tiên (bước tùy chọn: trả lại danh sách thứ hai cho trình gọi)
SparK

Câu trả lời:


133

Trong trường hợp cụ thể này , bạn nên xóa các phần tử theo thứ tự giảm dần. Chỉ mục đầu tiên 5, sau đó 3, sau đó 1. Điều này sẽ loại bỏ các yếu tố khỏi danh sách mà không có tác dụng phụ không mong muốn.

for (int j = i.length-1; j >= 0; j--) {
    list.remove(i[j]);
}

1
ArrayList của OP chứa Strings chứ không phải Integers (tuy nhiên, tôi đồng ý với quan sát của bạn).
Alex Lockwood

@Alex: Câu trả lời này sẽ hiệu quả nhưng nó thiếu sót như logic của OP trong câu hỏi của họ. Chúng ta đang nói về ArrayList<E>- tại sao mọi người lại muốn xóa một đối tượng khỏi một ArrayListvị trí hoàn toàn dựa trên thay vì kiểm tra xem ở vị trí đó có gì? OP cũng có thể được sử dụng Stringlàm kiểu đối tượng cho ArrayListnhưng câu trả lời của bạn là thực hành mã hóa không tốt cho generic ngay cả khi nó giải quyết được tình huống cụ thể của OP.
Squonk

3
Vâng tôi đồng ý với bạn. Nhưng OP hỏi về ArrayList<String>, không phải ArrayList<E>.
Adrian Monk

Tôi hoàn toàn không đồng ý với câu trả lời này, @MisterSquonk ya thuyết phục, giải pháp phải chung chung. Hơn nữa tại sao tôi lại nhận được downvote?
Mohammed Azharuddin Shaikh

66
OK, nghe này ... Tôi không biết vấn đề lớn là gì. OP đã đăng mã của anh ấy và tôi đã trả lời bằng một câu trả lời minh họa cách khắc phục có thể xảy ra. Tôi xin lỗi vì tôi đã không vượt lên trên bằng cách đưa ra một giải pháp hoàn toàn chung chung ... nhưng theo như tôi có thể nói, OP đã không yêu cầu một bài học lập trình. Anh ấy đang hỏi "tại sao mã này không hoạt động?" Đừng bắt đầu đổ lỗi cho tôi vì đã bỏ phiếu từ chối câu trả lời của bạn chỉ vì bạn diễn giải câu hỏi theo cách khác.
Alex Lockwood

30

Bạn có thể xóa các phần tử khỏi ArrayListviệc sử dụng ListIterator,

ListIterator listIterator = List_Of_Array.listIterator();

 /* Use void remove() method of ListIterator to remove an element from List.
     It removes the last element returned by next or previous methods.
 */
listIterator.next();

//remove element returned by last next method
listIterator.remove();//remove element at 1st position
listIterator.next();
listIterator.next();
listIterator.remove();//remove element at 3rd position
listIterator.next();
listIterator.next();
listIterator.remove();//remove element at 5th position

Cách tốt hơn và tốt hơn là sử dụng phương thức ListIterator remove () để xóa các đối tượng khỏi Bộ sưu tập trong Java, vì có thể có một luồng khác đang sửa đổi cùng một bộ sưu tập và có thể dẫn đến ConcurrentModificationException.
Min

10
 public void DeleteUserIMP(UserIMP useriamp) {
       synchronized (ListUserIMP) {
            if (ListUserIMP.isEmpty()) {
            System.out.println("user is empty");
        }  else {
            Iterator<UserIMP> it = ListUserIMP.iterator();
            while (it.hasNext()) {
                UserIMP user = it.next();
                if (useriamp.getMoblieNumber().equals(user.getMoblieNumber())) {
                    it.remove();
                    System.out.println("remove it");
                }
            }
            // ListUserIMP.remove(useriamp);

            System.out.println(" this user removed");
        }
        Constants.RESULT_FOR_REGISTRATION = Constants.MESSAGE_OK;
        // System.out.println("This user Deleted " + Constants.MESSAGE_OK);

    }
}

7

Như đã đề cập trước đó

iterator.remove()

có lẽ là cách an toàn duy nhất để loại bỏ các mục danh sách trong vòng lặp.

Để hiểu sâu hơn về việc xóa các mục bằng trình lặp, hãy thử xem chuỗi này


Tôi không nhận được phiếu bầu, tôi hoàn toàn đồng ý với bạn. Đây là cách an toàn nhất để làm như vậy.
Simmant

3

Tôi giả sử mảng tôi được sắp xếp tăng dần, đây là một giải pháp khác với Iterator, nó chung chung hơn:

ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
list.add("F");
list.add("G");
list.add("H");

int i[] = {1,3,5};

Iterator<String> itr = list.iterator();
int pos = 0;
int index = 0;
while( itr.hasNext() ){
    itr.next();
    if( pos >= i.length ){
        break;
    }
    if( i[pos] == index ){
        itr.remove();
        pos++;
    }

    index++;
}

2

Còn cái này thì sao? Chỉ cần suy nghĩ về nó-

import java.util.ArrayList;

class Solution
{
        public static void main (String[] args){

             ArrayList<String> List_Of_Array = new ArrayList<String>();
             List_Of_Array.add("A");
             List_Of_Array.add("B");
             List_Of_Array.add("C");
             List_Of_Array.add("D");
             List_Of_Array.add("E");
             List_Of_Array.add("F");
             List_Of_Array.add("G");
             List_Of_Array.add("H");

             int i[] = {1,3,5};

             for (int j = 0; j < i.length; j++) {
                 List_Of_Array.remove(i[j]-j);
             }

             System.out.println(List_Of_Array);

        }


}

Và đầu ra là-

[A, C, E, G, H]

2

Hãy thử theo cách này,

ArrayList<String> List_Of_Array = new ArrayList<String>();
List_Of_Array.add("A");
List_Of_Array.add("B");
List_Of_Array.add("C");
List_Of_Array.add("D");
List_Of_Array.add("E");
List_Of_Array.add("F");
List_Of_Array.add("G");
List_Of_Array.add("H");

int i[] = {5,3,1};

for (int j = 0; j < i.length; j++) {
    List_Of_Array.remove(i[j]);
}


2

Nếu bạn sử dụng "=", một bản sao được tạo cho danh sách mảng ban đầu trong danh sách thứ hai, nhưng tham chiếu giống nhau, vì vậy nếu bạn thay đổi trong một danh sách, danh sách kia cũng sẽ được sửa đổi. Sử dụng cái này thay cho "="

        List_Of_Array1.addAll(List_Of_Array);

2

phương thức remove (int index) của mảng danh sách loại bỏ phần tử tại vị trí xác định (chỉ mục) trong danh sách. Sau khi xóa các mục trong danh sách mảng sẽ chuyển bất kỳ phần tử nào tiếp theo sang trái.

Có nghĩa là nếu danh sách mảng chứa {20,15,30,40}

Tôi đã gọi phương thức: arraylist.remove (1)

sau đó dữ liệu 15 sẽ bị xóa và 30 & 40 hai mục này sẽ được dịch chuyển 1.

Vì lý do này, bạn phải xóa mục chỉ mục cao hơn của danh sách mảng trước.

Vì vậy, đối với tình huống đã cho của bạn..mã sẽ là ..

ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
list.add("F");
list.add("G");
list.add("H");

int i[] = {1,3,5};

for (int j = i.length-1; j >= 0; j--) {
    list.remove(i[j]);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.