如何从Java ArrayList中删除元素
如果需要用Java从ArrayList中删除元素,则有3个选项。
- 使用ArrayList类的remove()方法删除元素。参见示例。
- 使用ArrayList返回的迭代器的remove()方法。参见示例。
- 从Java 8开始使用removeIf()方法。参见示例。
使用ArrayList的remove方法删除元素
ArrayList类中的remove()方法有两种变体
- remove(int index)–此方法删除此列表中指定索引处的元素。
- boolean remove(Object o)-此方法从列表中删除第一次出现的指定元素(如果存在)。
这是一个通过传递元素本身(使用remove(Object o)方法)从Java中的ArrayList中删除元素的示例。
import java.util.List; public class ListElementRemoval { public static void main(String[] args) { List<String> carList = new ArrayList<String>(); carList.add("Audi"); carList.add("BMW"); carList.add("Jaguar"); carList.add("BMW"); carList.add("Mini Cooper"); System.out.println("List elements- " + carList); // removing element carList.remove("Mini Cooper"); System.out.println("List elements after removal- " + carList); } }
输出:
List elements- [Audi, BMW, Jaguar, BMW, Mini Cooper] List elements after removal- [Audi, BMW, Jaguar, BMW]
使用迭代器的remove方法删除元素
如果要在迭代ArrayList时从ArrayList中删除元素,则应使用迭代器本身的remove()方法。这是必需的,因为除非通过迭代器自己的remove方法,否则不允许在创建迭代器后随时在结构上修改(添加或者删除元素)ArrayList,否则将引发ConcurrentModificationException。
让我们看一个例子,这里使用ArrayList类的remove方法在迭代List时删除了元素。
import java.util.Iterator; import java.util.List; public class ListElementRemoval { public static void main(String[] args) { List<String> carList = new ArrayList<String>(); carList.add("Audi"); carList.add("BMW"); carList.add("Jaguar"); carList.add("BMW"); carList.add("Mini Cooper"); // getting iterator Iterator<String> itr = carList.iterator(); while(itr.hasNext()){ String car = itr.next(); if(car.equals("Mini Cooper")) { // Using ArrayList's remove method carList.remove(car); } } } }
输出:
Exception in thread "main" java.util.ConcurrentModificationException at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:937) at java.base/java.util.ArrayList$Itr.next(ArrayList.java:891) at com.theitroad.ListElementRemoval.main(ListElementRemoval.java:19)
这是更改后的代码,其中迭代器的remove方法用于从ArrayList中删除元素。
public class ListElementRemoval { public static void main(String[] args) { List<String> carList = new ArrayList<String>(); carList.add("Audi"); carList.add("BMW"); carList.add("Jaguar"); carList.add("BMW"); carList.add("Mini Cooper"); System.out.println("List elements- " + carList); // getting iterator Iterator<String> itr = carList.iterator(); while(itr.hasNext()){ String car = itr.next(); if(car.equals("Mini Cooper")) { itr.remove(); } } System.out.println("List elements after removal- " + carList); } }
输出:
List elements- [Audi, BMW, Jaguar, BMW, Mini Cooper] List elements after removal- [Audi, BMW, Jaguar, BMW]
如我们所见,现在不会引发ConcurrentModificationException。
使用removeIf方法删除元素
从Java 8开始,我们还可以使用removeIf()方法从ArrayList中删除元素,该数组以Predicate作为参数,并删除所有满足给定Predicate的元素。
谓词是Java 8中添加的功能接口。
public class ListElementRemoval { public static void main(String[] args) { List<String> carList = new ArrayList<String>(); carList.add("Audi"); carList.add("BMW"); carList.add("Jaguar"); carList.add("BMW"); carList.add("Mini Cooper"); System.out.println("List elements- " + carList); carList.removeIf(c -> c.equalsIgnoreCase("Mini Cooper")); System.out.println("List elements after removal- " + carList); } }
remove()方法的自动装箱问题
由于ArrayList中的remove()方法具有很多变体,我们可以在其中传递索引或者要删除的对象。如果元素由于自动装箱而包装到其对应的包装器类,则这些重载的方法可能会引起问题。
让我们尝试以一个具有ArrayList of Integers的示例来阐明它。
public class ListElementRemoval { public static void main(String[] args) { List<String> carList = new ArrayList<String>(); carList.add("Audi"); carList.add("BMW"); carList.add("Jaguar"); carList.add("BMW"); carList.add("Mini Cooper"); System.out.println("List elements- " + carList); carList.removeIf(c -> c.equalsIgnoreCase("Mini Cooper")); System.out.println("List elements after removal- " + carList); } }
在这里,我们要传递要从ArrayList中删除的Integer对象6,但是将使用带有int参数作为参数的remove()方法。在这种情况下,不会进行自动装箱,并且会出现错误。
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 6 out-of-bounds for length 4 at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64) at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70) at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248) at java.base/java.util.Objects.checkIndex(Objects.java:372) at java.base/java.util.ArrayList.remove(ArrayList.java:517) at com.theitroad.ListElementRemoval.main(ListElementRemoval.java:16)
如果存在此类歧义,则应传递对象本身以进行删除。
public static void main(String[] args) { List<Integer> numebrList = new ArrayList<Integer>(); numebrList.add(3); numebrList.add(4); numebrList.add(5); numebrList.add(6); System.out.println("List elements- " + numebrList); // Passing object explicitly numebrList.remove(Integer.valueOf(6)); System.out.println("List elements after removal- " + numebrList); } }