Java中ArrayList如何删除指定位置的元素

这篇具有很好参考价值的文章主要介绍了Java中ArrayList如何删除指定位置的元素。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目标:list中有0到39共40个元素,删除其中索引是10、20、30的元素

方案一:使用普通for循环从前往后遍历再删除

初始化List列表
List<String> list = new ArrayList<>();
for (int i = 0; i < 40; i++) {
    list.add("element" + i);
}
复制代码

首先当我们删除第10位元素时,List会将后面的元素向前补位,之后再查第10位元素就会输出第11位元素

for (int i = 0; i < list.size(); i++) {
    if (i == 10) {
        list.remove(i);
    }
}
System.out.println(list.get(10));
复制代码
输出:element11
复制代码

那么删除了一个元素以后,后面需要删除的元素位置就向前提1位

/**
 * 如果明确需要删除元素的位置
 * 那么可以这样,每删除一个元素后就把下一个要删除元素的位置减1
 * 注意这么做有个需要注意的点,那就是每次删除完节点后遍历指针i需要减一,这样在删除两个临近节点时才不会出现问题
 * 比如要删除10和11
 */
for (int i = 0; i < list.size(); i++) {
    if (i == 10) {
        list.remove(i);
        i--;
    }
    if (i == 19) {
        list.remove(i);
        i--;
    }
    if (i == 28) {
        list.remove(i);
        i--;
    }
}

System.out.println(list.contains("element10"));
System.out.println(list.contains("element20"));
System.out.println(list.contains("element30"));
复制代码
输出:
 false
 false
 false
复制代码

当然我们可以用一个数组或列表从小到大存储需要删除的位置,然后再for循环中进行运算和取值

方案二:使用普通for循环从后往前遍历再删除

从后向前遍历的好处是我们不需要再像方案一一样每删除一个元素都需要去考虑后面元素向前补位的问题

for (int i = list.size() - 1; i >= 0; i--) {
    if (i == 30) {
        list.remove(i);
    }
    if (i == 20) {
        list.remove(i);
    }
    if (i == 10) {
        list.remove(i);
    }
}
System.out.println(list.contains("element10"));
System.out.println(list.contains("element20"));
System.out.println(list.contains("element30"));
复制代码
输出:
 false
 false
 false
复制代码

从后向前,即使后面进行元素进行向前补位操作也不会影响前面需要删除的元素

这里也可以用一个数组或列表存储需要删除的元素,从大到小排列,取出一个删除一个

方案三:使用迭代器删除

Iterator<String> iterator = list.iterator();
int i = 0;
while (iterator.hasNext()) {
    String next = iterator.next();
    if (i == 10) {
        iterator.remove();
    }
    i++;
}
System.out.println(list.get(10));
System.out.println(list.contains("element10"));
复制代码
输出:
element11
false
复制代码

在迭代器中维护一个数字i标识遍历的位置

如果我们在迭代器中继续删除另外20和30位置元素

Iterator<String> iterator = list.iterator();
int i = 0;
while (iterator.hasNext()) {
    String next = iterator.next();
    if (i == 10) {
        iterator.remove();
    }
    if (i == 20) {
        iterator.remove();
    }
    if (i == 30) {
        iterator.remove();
    }
    i++;
}
System.out.println(list.get(10));
System.out.println(list.contains("element10"));
System.out.println(list.get(20));
System.out.println(list.contains("element20"));
System.out.println(list.get(30));
System.out.println(list.contains("element30"));
复制代码
输出:
element11
false
element22
false
element33
false
复制代码

首先我们在迭代过程中指定的是删除10、20、30三个位置的元素,可以看到输出contains时都是false表示正确删除,但是最终输出列表的值发现对应索引位置已经进行了补位。

我们debug分析一下为什么

先简单介绍一下Iterator和Iterable

  • Iterable是一个迭代接口,实现了这个接口代表该类可以迭代

可以看到我们的集合Collection接口就是它的子类

Java中ArrayList如何删除指定位置的元素

它有一个主要方法:

// 返回一个实现了Iterator接口的对象,我们也是用这个对象去进行迭代
Iterator<T> iterator();
复制代码
  • Iterator,它主要有三个方法:
// 返回是否还有下一个元素
boolean hasNext();
// 返回下一个元素
E next();
// 删除该元素
default void remove() {
    throw new UnsupportedOperationException("remove");
}
复制代码

每个不同的集合类都会有不同的Iterator接口实现,在ArrayList中使用了一个内部类来实现

private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;

    Itr() {}
}
复制代码

我们通过list.iterator()拿到的就是这个内部类的对象实例,这个类中有两个字段cursor和lastRet,这两个字段就是我们能在迭代器中正确删除对应位置的元素的关键。

有关expectedModCount和modCount的问题后面会补充,我们先不用关注

cursor初始化是0 lastRet初始化是-1

分析next和remove方法的源码

/**
* 可以先不关注这两个Exception
* 每次调用next() cursor都会+1 而lastRet就会变成之前cursor的值
* cursor初始化是0
* lastRet初始化是-1
* 调用一次以后  cursor是1 lastRet变成0
**/
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];
}

public void remove() {
    if (lastRet < 0)
        throw new IllegalStateException();
    checkForComodification();

    try {
        // 调用本身的remove方法
        ArrayList.this.remove(lastRet);
        cursor = lastRet;
        lastRet = -1;
        expectedModCount = modCount;
    } catch (IndexOutOfBoundsException ex) {
        throw new ConcurrentModificationException();
    }
}
复制代码

关键是这个remove方法对cursor和lastRet的修改

假如正在删除第10个元素

执行remove方法前cursor应该是11,lastRet是10

执行了以后lastRet变成了-1,cursor变成了10

下次执行next()方法返回的元素其实还是elementData[10]也就是List补位后正确的下一个元素,cursor变成了11,lastRet是10

总结:使用迭代器遍历时ArrayList会用lastRet和cursor两个变量来维护当前遍历的元素索引和下一次需要遍历元素的索引,通过这两个变量就可以实现迭代中正确的删除某个位置的元素。文章来源地址https://www.toymoban.com/news/detail-400351.html

到了这里,关于Java中ArrayList如何删除指定位置的元素的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • hive表新增字段,指定新增字段位置,删除字段

    背景:项目中,客户使用hive内表,由于逻辑变更,原hive表结构需要调整,新增字段。 一、新增字段 遇到hive表新增字段,以往建表都是建外表,直接drop后,重新创建。由于这次全部使用内表创建的,所以使用add column功能新增字段。 但是发现,如果已经存在记录的情况下覆

    2024年02月09日
    浏览(35)
  • JS循环遍历并删除指定元素

    昨天一个朋友让我帮她修改的一段代码: 需求要每条数据轮播1分钟,然后删除,运行的时候会发现foreach循环中,删除一个之后,其他的就无法删除了。 【分析原因】 数据格式例如:[\\\'a\\\',\\\'b\\\',\\\'b\\\',\\\'c\\\'],需求是删除item为‘b’的元素 第一次循环:SysNotices数据:[\\\'a\\\',\\\'b\\\',\\\'b\\\',\\\'c\\\'],in

    2024年02月09日
    浏览(39)
  • List集合删除指定元素-四种方法

    第一种 for循环 输出结果为 第二种 迭代器 输出结果为 第三种 stream流 这种过滤是留下符合条件的元素 输出结果为 第四种 removeIf 方法以及 方法引用 removeIf 方法是jdk1.8 Collection以及其子类新增的,作用是过滤指定条件的元素 输出结果为 总结 不言而喻,第四种方法最好用。

    2024年02月09日
    浏览(43)
  • 使用scrollTo/scrollTop让页面元素滚动到指定位置, 并设置滚动动画

    当容器有滚动条时,有时需要点击 试图 或 节点 将页面滚动到指定元素位置 比如父元素设置了 overflow: hidden; ,当元素里的内容超过元素本身的高度时, 就会出现滚动条, 那么鼠标滑动的距离就是其滚动距离. scrollTop属性 scrollTop 就是指 “元素中的内容” 超出 “元素上边界” 的

    2023年04月27日
    浏览(66)
  • 删除数组中的指定元素或数组对象

    1.删除数组中的某个指定元素 1)首先获取元素下标,用indexOf()函数找到他的位置index,如果没有找到这个元素那么index将会等于-1;如下为找到元素2的下标 var array = [1,2,3]; var index = array.indexOf(2); 2)使用splice进行移除,删除第index位置的指定个数的元素,splice直接修改原数组,并

    2024年02月11日
    浏览(46)
  • C语言 - 删除数组中的指定元素(Delete)

    目录   引言: 题目说明: 举例分析: 初始状态: step 1:  Step 2:  Step 3 :  Step 4 :  将最后一个元素赋值为0  Step 5 :将i下标向前迁移一位(重复判断): 代码实现:  总结:   这是数组中一个比较简单的题目,今天把它单独拎出来的原因就是在我即将要写的数据结构的顺

    2023年04月09日
    浏览(38)
  • 如何删除数组中的某个元素(C/Python/Java/Go/MATLAB)

    加粗样式 根据之前的文章分享《GitHub 2022 的趋势和见解》,可以看到各种开发语言在最近几年的使用人群占权比,个人也感觉Python是特别受欢迎的。 下面针对几种语言做了简单介绍,并简单写了下《如何删除数组中的某个元素》的实现逻辑和代码示例,希望对看到人有帮助

    2024年02月06日
    浏览(40)
  • python 一次性删除列表(list)的空白元素(空内容) 或者 一次性删除列表(list)中的指定元素

    看看下述代码: 输出: 当你遇见这种情况,有哪些方法来去除里面的空内容呢(即 \\\'\\\' )? 1.1 删除空内容(方法一) : 输出: 1.2 删除空内容(方法二) : 需要 配合 lambda 表达式 一起使用! 输出: 2.3 删除指定内容 : 输出: 注 :此方法既可以删除空元素,也可以删除指

    2024年02月03日
    浏览(45)
  • std::list和std::vector删除指定下标的元素

    list和vector都可以使用erase函数移除指定下标的元素,注意输入的是迭代器,返回值为指向下一个元素的位置。: 如果下标是index,直接调用即可: 如果根据下标一次性删除多个元素,则会发生错误,因为删除一个元素后,元素个数会发生变化,因此下标就会出现错误,正确代

    2024年02月11日
    浏览(44)
  • 从生活入手学编程(2):js删除指定元素的15种方法

    1. 使用filter()方法: 2. 使用splice()方法: 3. 使用forEach()方法和slice()方法: 4. 使用reduce()方法: 5. 使用for循环和splice()方法: 6. 使用filter()方法和includes()方法: 7. 使用for循环和slice()方法: 8. 使用for循环和push()方法: 9. 使用filter()方法和indexOf()方法: 10. 使用for循环和concat()方

    2024年01月15日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包