remove()方法有两种移除方式:
1、根据下标移除:public E remove(int index)
2、根据内容移除:public boolean remove(Object o)
List测试数据如下
List<Integer> list1 = Arrays.asList(4,2,3,5,1,2,2,7,6);
List<Integer> list = new ArrayList<>(list1);
错误方式1 根据初时大小,for循环
public static void way0(List<Integer> list) {
int len = list.size();
for (int i = 0; i < len; i++) {
if (2 == list.get(i)) {
list.remove(i);
}
}
}
这样会抛出如下异常:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 7, Size: 7
at java.util.ArrayList.rangeCheck(ArrayList.java:659)
at java.util.ArrayList.get(ArrayList.java:435)
原因:数组越界。删除元素之后未改变相应角标,遍历到最后一个的时候就会找不到,抛出上方的异常。
错误方式2 for循环
public static void way1(List<Integer> list) {
for (int i = 0; i < list.size(); i++) {
if (2 == list.get(i)) {
list.remove(i);
}
}
}
问题:删除某个元素后,List的size大小会变化,而遍历的索引也在变化,会导致遍历的时候漏掉某些元素。比如本文的示例,会漏掉最后那个2,因为删除某个元素后,后方的元素都会往前移动一位。
结论:此方式可用在删除特定的一个元素时使用,但不适合循环删除多个元素。
错误方式3 增强for循环
public static void way2(List<Integer> list) {
for (int i: list) {
if (2 == i) {
list.remove(i);
}
}
}
此方法会抛出如下异常:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911)
at java.util.ArrayList$Itr.next(ArrayList.java:861)
因为元素在使用的时候发生了并发的修改,导致异常抛出。
错误方式4 iterator遍历,使用list的remove()方法
public static void way3(List<Integer> list) {
Iterator<Integer> iterator = list.iterator();
int i = iterator.next();
while (iterator.hasNext()) {
if (2 == iterator.next()) {
list.remove(i);
}
}
}
同样会抛出方式3的异常
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911)
at java.util.ArrayList$Itr.next(ArrayList.java:861)
正确方法1 iterator遍历,使用iterator的remove()方法
public static void way4(List<Integer> list) {
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
if (2 == iterator.next()) {
iterator.remove();
}
}
}
正确方法2 java8开始的写法,内部也是用的iterator实现
public static void way5(List<Integer> list) {
list.removeIf(integer -> 2 == integer);
}
正确方法3 删除下标及定位到遍历的位置
public static void way6(List<Integer> list) {
int len = list.size();
for (int i = 0; i < len; i++) {
if (2 == list.get(i)) {
list.remove(i);
len--;
i--;
}
}
}
正确方法4 从后往前遍历
public static void way7(List<Integer> list) {
int len = list.size();
for (int i = len - 1; i >= 0 ; i--) {
if (2 == list.get(i)) {
list.remove(i);
}
}
}
public static void way8(List<Integer> list) {
for (int i = list.size() - 1; i >= 0 ; i--) {
if (2 == list.get(i)) {
list.remove(i);
}
}
}