一些背景:我是Java新手,正在学习基本的Java类。我目前正在上课的最后一个项目,并完成了除最后一部分代码以外的所有内容。由于某种原因,我最困难的时间是从数组列表中删除一个元素。这是我正在处理的代码:
public static void delete(String bookID) {
for (book eachElement : catalog) {
if (eachElement.getBookID().equals(bookID)) {
catalog.remove(eachElement);
return;
}
}
}
代码执行,没有运行时错误,但不会删除任何内容。 另外,我知道一切都可以在remove语句之前完成,因为我还有另一种方法,它使用带有select bookID字符串的for和if语句进行相同的精确计算。
答案 0 :(得分:5)
您需要使用迭代器,否则您将获得java.util.ConcurrentModificationException
public static void delete(String bookID) {
for (Iterator<Book> it = catalog.listIterator(); it.hasNext(); ) {
Book book = it.next();
if (book.getBookID().equalsIgnoreCase(bookID)) {
it.remove(book);
return;
}
}
}
注意:equalsIgnoreCase用于丢弃大小写差异。
抛出 java.util.ConcurrentModificationException
的原因是您在列表中执行了2个操作:迭代和删除。因此,实际上,还有另一种方法-在迭代的每个步骤中复制列表。
public static void delete(String bookID) {
for (Book book : new ArrayList<>(catalog)) {
if (book.getBookID().equalsIgnoreCase(bookID)) {
catalog.remove(book);
return;
}
}
}
注意:出于性能方面的考虑(二次内存使用和每步线性删除),我不建议使用最后一种方法。我举这个例子只是为了强调抛出java.util.ConcurrentModificationException
的根本原因。
答案 1 :(得分:5)
当您处于forEach循环中时,您不应也不能从集合中删除元素。
请阅读Java中ArrayList的文档。
https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html
实际上,您可以看到ArrayList.remove(Object o)在列表中删除了o,因此不需要您的方法。
因此答案是,找到带有ID的书“对象”,然后将其删除。或者最好使用地图存储数据。
您的情况应该是
Book b = null;
for(Book book : books) {
if(book.getBookId().equals(bookId)) {
b = book.getBookId();
break;
}
}
books.remove(b);
或者如果您正在使用Java8,那么您实际上应该是:D
books.stream().filter(b -> b.getBookId().equals(bookId)).getFirst().ifPresent(books::remove);
答案 2 :(得分:2)
在使用迭代器时,元素的删除是未定义的。更好的方法是使用removeIf。
catalog.removeIf(eachElement -> eachElement.getBookID().equals(bookId));
答案 3 :(得分:0)
使用loop时,您需要使用迭代器才能删除项目。 还要仔细检查ID是否存在(制作一些System.out.println(“ test”)并检查它是否正在进入作用域)。