天天看點

java list 疊代 删除_Java疊代時從集合中删除元素

小編典典

讓我舉幾個例子,并提出一些避免方案ConcurrentModificationException。

假設我們有以下藏書

List books = new ArrayList();

books.add(new Book(new ISBN("0-201-63361-2")));

books.add(new Book(new ISBN("0-201-63361-3")));

books.add(new Book(new ISBN("0-201-63361-4")));

收集并删除

第一種技術是收集所有要删除的對象(例如,使用增強的for循環),并在完成疊代後删除所有找到的對象。

ISBN isbn = new ISBN("0-201-63361-2");

List found = new ArrayList();

for(Book book : books){

if(book.getIsbn().equals(isbn)){

found.add(book);

}

}

books.removeAll(found);

假設你要執行的操作是“删除”。

如果要“添加”此方法也可以,但是我認為你将周遊另一個集合,以确定要添加到第二個集合中的元素,然後addAll在最後發出一個方法。

使用ListIterator

如果要使用清單,則另一種技術是使用ListIterator,它支援在疊代過程中删除和添加項目。

ListIterator iter = books.listIterator();

while(iter.hasNext()){

if(iter.next().getIsbn().equals(isbn)){

iter.remove();

}

}

同樣,我在上面的示例中使用了“删除”方法,這似乎是你的問題所暗示的含義,但是你也可以add在疊代過程中使用其方法添加新元素。

使用JDK> = 8

對于使用Java 8或更高版本的使用者,你可以使用多種其他技術來利用它。

你可以removeIf在Collection基類中使用新方法:

ISBN other = new ISBN("0-201-63361-2");

books.removeIf(b -> b.getIsbn().equals(other));

或使用新的流API:

ISBN other = new ISBN("0-201-63361-2");

List filtered = books.stream()

.filter(b -> b.getIsbn().equals(other))

.collect(Collectors.toList());

在後一種情況下,要從books = filtered集合中過濾元素,你可以将原始引用重新配置設定給過濾後的集合(即),或将過濾後的集合用于removeAll從原始集合中找到的元素(即books.removeAll(filtered))。

使用子清單或子集

還有其他選擇。如果清單已排序,并且要删除連續的元素,則可以建立一個子清單,然後清除它:

books.subList(0,5).clear();

由于子清單由原始清單支援,是以這将是删除此元素子集合的有效方法。

使用NavigableSet.subSet方法或那裡提供的任何切片方法,可以通過排序集實作類似的效果。

注意事項:

你使用哪種方法可能取決于你打算做什麼

removeAl集合和技術可與任何集合(集合,清單,集合等)一起使用。

該ListIterator技術顯然僅适用于清單,隻要它們的給定ListIterator實作為添加和删除操作提供支援。

該Iterator方法适用于任何類型的集合,但僅支援删除操作。

使用ListIterator/ Iterator方法,明顯的優點是不必複制任何内容,因為我們在疊代時将其删除。是以,這非常有效。

JDK 8流示例實際上并未删除任何内容,而是查找所需的元素,然後我們用新的引用替換了原始的收集引用,并讓舊的引用進行了垃圾收集。是以,我們隻對集合進行一次疊代,這樣會很有效。

在收集和removeAll進行中,缺點是我們必須疊代兩次。首先,我們在foor循環中進行疊代,以尋找一個符合移除條件的對象,一旦找到該對象,便要求将其從原始集合中移除,這意味着需要進行第二次疊代來尋找該對象,以便去掉它。

我認為值得一提的是,該Iterator接口的remove方法在Javadocs中被标記為“可選”,這意味着如果我們調用remove方法,可能會Iterator抛出一些實作UnsupportedOperationException。是以,如果我們不能保證疊代器支援删除元素,那麼這種方法将不如其他方法安全。

2020-03-11