Collection trong Java

Trong java có 1 framework gọi là Collections. Framework này được đặt trong package java.utils. Nó cung cấp 1 tập hợp các generic class bao gốm các hàm xử lý dữ liệu liên quan đến list mà Array không thể giúp chúng ta giải quyết.

Hãy thử tìm hiểu 1 số phương thức cần biết khi làm việc với Collections

Xóa 1 phần tử của List trong vòng lặp for.

Việc xóa 1 phần tử trong khi duyệt list là 1 việc làm tương đối thường xuyên trong các bài toán thực tế. Ví dụ như ta có 1 list chứa các đối tượng NewsAds. (Dạng này hay gặp ở các app tin tức, khi ta muốn chèn các quảng cáo vào list danh sách tin). Giờ ta chỉ muốn lọc ra các đối tượng News (tức là xóa bỏ đi các đối tượng Ads) trong list. Ta sẽ làm thế nào. Mình sẽ chỉ ra 1 số cách làm sai, và 1 số cách làm đúng. Hãy theo dõi.

Mình có listNews như sau:

List listNews = new ArrayList<>();

listNews.add(new NewsItem());

listNews.add(new NewsItem());

listNews.add(new NewsItem());

listNews.add(new AdsItem());

listNews.add(new AdsItem());

listNews.add(new AdsItem());

Và mình muốn xóa các AdsItem.

Các phương thức làm sai thường gặp

Cách làm sai 1:

for(int i=0;i<listNews.size();i++){

    if(listNews.get(i) instanceof AdsItem){

    listNews.remove(i);

    }

}

Với cách làm này, ta sẽ thử kiểm nghiệm kết quả:

for(int i=0;i<listNews.size();i++){

    System.out.println(listNews.get(i).getClass());

}

Kết quả:

class NewsItem

class NewsItem

class NewsItem

class AdsItem

Vì sao cách này sai. Trong vòng lặp, đối tượng AdsItem cuối ko bị xóa đi do i chỉ chạy đến 3, do phần tử AdsItem trước bị xóa. Dẫn đến size của list bị giảm xuống 4 => i chỉ chạy đến 3. Đồng nghĩa với việc đối tượng AdsItem cuối cùng (chỉ số ban đầu là 4) – không bị động tới.

Cách làm sai 2:

for(Object o:listNews){

    if(o instanceof AdsItem){

        listNews.remove(o);

    }

}

Cách này sẽ gây ra exception  java.util.ConcurrentModificationException. Nguyên nhân bởi ta đã duyệt và xóa phần tử tại cùng 1 thời điểm.

Cách làm đúng

Sử dụng Iterator:

Iterator iterator = listNews.iterator();

    while(iterator.hasNext()){

        if(iterator.next() instanceof AdsItem){

        iterator.remove();

    }

}

Ta thử kiểm nghiệm kết quả:

class NewsItem

class NewsItem

class NewsItem

Lúc này ta đã sử dụng đến Iterator, đây là interface cung cấp cho ta phương thức remove dùng để xóa phần tử trong list tạo ra nó.

Cách 2: Sử dụng list should-be-removed:

Ý tưởng chính của cách này là sao chép các phần tử cần xóa sang 1 list mới, sau đó sử dụng hàm removeAll đối với list cũ.

List shoudBeRemoved = new ArrayList<>();

for (Object o : listNews) {

    if (o instanceof AdsItem) {

    shoudBeRemoved.add(o);

    }

}

listNews.removeAll(shoudBeRemoved);

Cách 3: Sử dụng removeIf

Cách này cực kỳ đơn giản so với 2 cách trên:

listNews.removeIf(p-> p instanceof AdsItem);

Done!

Sub Collection

Đang viết…

Removing matching items from Lists using Iterator

Đang viết…

Join lists

Đang viết

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *