当前位置:   article > 正文

List遍历删除元素remove()_list remove

list remove

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

6、普通for循环 --> 倒序方式

二、源码篇


1、普通for循环出错原因

public boolean remove(Object o) {

if (o == null) {

for (int index = 0; index < size; index++)

if (elementData[index] == null) {

fastRemove(index);

return true;

}

} else {

for (int index = 0; index < size; index++)

if (o.equals(elementData[index])) {

fastRemove(index);

return true;

}

}

return false;

}

/*

  • Private remove method that skips bounds checking and does not

  • return the value removed.

*/

private void fastRemove(int index) {

modCount++;

int numMoved = size - index - 1;

if (numMoved > 0)

//remove会导致之后的元素往前移动,而下标不改变时就会出现bug

System.arraycopy(elementData, index+1, elementData, index,

numMoved);

elementData[–size] = null; // clear to let GC do its work

}

我们在删除某个元素后,list的大小发生了变化,这时候你的的索引也会发生变化,这时就会导致你在遍历的时候漏掉某些元素。

比如当你删除第1个元素后,我们如果还是继续根据索引访问第2个元素时,因为删除的关系,后面的元素都往前移动了一位,所以实际访问的是第3个元素。

所以这种方式可以用在删除特定的一个元素时使用,但不适合循环删除多个元素时使用。

2、高级for循环出错原因

foreach其实是用迭代器来进行遍历的,而在遍历时直接使用arraylist的remove方法会导致什么问题呢?

可以再看一下fastremove和迭代器遍历的内部代码:

最后导致抛出上面异常的其实就是这个,简单说,调用list.remove()方法导致modCount和expectedModCount的值不一致而报异常

final void checkForComodification() {

if (modCount != expectedModCount)

throw new ConcurrentModificationException();

}

//调用next时会调用checkForComodification方法检查 这两个字段

//而fastRemove里面只对modCount 进行了改变 导致抛出异常

public E next() {

checkForComodification();

int i = cursor;

if (i >= size)

throw new NoSuchElementException();

Object[] elementData = ArrayList.this.elementData;

if (i >= elementData.length)

throw new ConcurrentModificationException();

cursor = i + 1;

return (E) elementData[lastRet = i];

}

所以遍历时remove并不适用于foreach。

3、java8中新方法removeIf

//内部其实就是迭代器遍历

default boolean removeIf(Predicate<? super E> filter) {

Objects.requireNonNull(filter);

boolean removed = false;

final Iterator each = iterator();

while (each.hasNext()) {

if (filter.test(each.next())) {

each.remove();

removed = true;

}

}

return removed;

}

总结

在这里,由于面试中MySQL问的比较多,因此也就在此以MySQL为例为大家总结分享。但是你要学习的往往不止这一点,还有一些主流框架的使用,Spring源码的学习,Mybatis源码的学习等等都是需要掌握的,我也把这些知识点都整理起来了

面试真题

Spring源码笔记

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
这些知识点都整理起来了

[外链图片转存中…(img-H4JQu133-1714513725309)]

[外链图片转存中…(img-qKA4bN3Z-1714513725309)]

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/957991
推荐阅读
相关标签
  

闽ICP备14008679号