Java集合删除元素ArrayList实例详解

Java集合删除元素ArrayList实例详解

AbstractCollection集合类中有一个remove方法,该方法为了适配多种不同的集合,允许删除空的元素,看这部分代码的时候产生了疑问,为什么这里直接用it.remove()就直接删除了?

public boolean remove(Object o) {
    Iterator<E> it = iterator();
    if (o==null) {
      while (it.hasNext()) {
        if (it.next()==null) {
          it.remove();
          return true;
        }
      }
    } else {
      while (it.hasNext()) {
        if (o.equals(it.next())) {
          it.remove();
          return true;
        }
      }
    }
    return false;
  }

接下来,拿ArrayList为例子,进行说明。其继承结构如下图所示。并且,ArrayList内部有其使用的Iterator的实现类。

编写一段测试代码:

AbstractCollection<String> list = new ArrayList<>();
    list.add("a");
    list.add(null);
    list.add(null);

    Iterator<String> iter = list.iterator();
    while(iter.hasNext()) {
      if(iter.next() == null) {
        iter.remove();
      }
    }
    System.out.println(list);

关键点还是在于iter.next() == null 这一行,next的源码如下:

 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];
    }

cusor在这里表示的是遍历时的索引,在调用next方法的时候其实cusor已经指向了当前元素的下一个元素,而使用lasrRet来获取当前的索引上的数据并将其返回。

而remove()方法中是通过lastRet的索引进行删除的。

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

      try {
        ArrayList.this.remove(lastRet);
        cursor = lastRet;
        lastRet = -1;
        expectedModCount = modCount;
      } catch (IndexOutOfBoundsException ex) {
        throw new ConcurrentModificationException();
      }
    }

借助上文中提到的测试实例,可以进行每一步的推算。

1. 调用next()方法,cursor指向0号元素,i被赋值为cursor的值,然后cursor被修改为i+1,指向了1号元素,也就是null所在的位置, lastRet被赋值为0。
2. 调用next()方法,cursor指向了1号元素,赋值给i,然后cursor又通过i+1递增变为2,lastRet被赋值为1
3. 执行删除,删除该集合lastRet上所代表的元素。删除完成后修改cursor指针同时使得expectedModCount和modCount保持一致避免fastfail。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • Java中Arraylist动态扩容方法详解

    前言 本文主要给大家介绍了关于Java中Arraylist动态扩容的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. ArrayList 概述 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长.ArrayList不是线程安全的,只能用在单线程环境下.实现了Serializable接口,因此它支持序列化,能够通过序列化传输:实现了RandomAccess接口,支持快速随机访问,实际上就是通过下标序号进行快速访问:实现了Cloneable接口,能被克隆.

  • 对arraylist中元素进行排序实例代码

    rrayList中的元素进行排序,主要考查的是对util包中的Comparator接口和Collections类的使用. 实现Comparator接口必须实现compare方法,自己可以去看API帮助文档. 创建一个Comparator实例后,用Collections.sort(List,<E>)对List中的元素进行排序. 下面是实现代码: 以下文件必须引入util包: package com.test; import Java.util.*; Emp.java文件如下: class Emp

  • Java 中模仿源码自定义ArrayList

    Java 中模仿源码自定义ArrayList 最近看了下ArrayList的源码,抽空根据ArrayList的底层结构写了一个功能简单无泛型的自定义ArrayLsit,帮助自己更好理解ArrayList:,其实现的底层数据结构为数Object组,代码如下: /** * 自己实现一个ArrayList * */ public class MyArrayList { private Object[] elementData; private int size; public int size(){

  • java并发容器CopyOnWriteArrayList实现原理及源码分析

    CopyOnWriteArrayList是Java并发包中提供的一个并发容器,它是个线程安全且读操作无锁的ArrayList,写操作则通过创建底层数组的新副本来实现,是一种读写分离的并发策略,我们也可以称这种容器为"写时复制器",Java并发包中类似的容器还有CopyOnWriteSet.本文会对CopyOnWriteArrayList的实现原理及源码进行分析. 实现原理 我们都知道,集合框架中的ArrayList是非线程安全的,Vector虽是线程安全的,但由于简单粗暴的锁同步机制,

  • Java中ArrayList的removeAll方法详解

    本文介绍的是关于Java中ArrayList的removeAll方法的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: 在开发过程中,遇到一个情况,就是从所有骑手Id中过滤没有标签的骑手Id(直接查询没有标签的骑手不容易实现), List<Integer> allRiderIdList = new ArrayList(); // 所有的骑手,大致有23W数据 List<Integer> hasAnyTagRiderId = new ArrayList(); // 有标签

  • Java中ArrayList去除重复元素(包括字符串和自定义对象)

    1.去除重复字符串 package com.online.msym; import java.util.ArrayList; import java.util.Iterator; @SuppressWarnings({ "rawtypes", "unchecked" }) public class Demo1_ArrayList { public static void main(String[] args) { ArrayList list = new Array

  • Java集合删除元素ArrayList实例详解

    Java集合删除元素ArrayList实例详解 AbstractCollection集合类中有一个remove方法,该方法为了适配多种不同的集合,允许删除空的元素,看这部分代码的时候产生了疑问,为什么这里直接用it.remove()就直接删除了? public boolean remove(Object o) { Iterator<E> it = iterator(); if (o==null) { while (it.hasNext()) { if (it.next()==null) { i

  • Java集合教程之Collection实例详解

    前言 集合就是一组数的集合,就像是一个容器,但是我们应该清楚的是集合中存放的都是对象的引用,而不是真正的实体.而我们常说的集合中的对象其实指的就是对象的引用. 我们可以把集合理解为一个小型数据库,用于存放数据,我们对集合的操作也就是数据的增删改查,在 Java 中有两个顶层接口 Collection 和 Map 用于定义和规范集合的相关操作.这篇文章主要说一下集合框架中的 Collection 部分. Collection 表示一组对象,这些对象可以是有序也可以是无序的,它提供了不同的子接口满足

  • Java集合功能与用法实例详解

    本文实例讲述了Java集合功能与用法.分享给大家供大家参考,具体如下: 本文内容: 什么是集合 Collection Iterator List set Map Collections工具类 首发日期:2018-05-17 什么是集合: 集合是一种新容器,集合可以存储数量不固定的元素(数组的空间是固定的,你申请多少空间以后都不能改变),而集合可以动态的增加空间(有些是空间不够时新建一个足够大的数组再把原来的元素移到新的数组中). 集合的出现解决的几个问题: 存储数量不等的元素. 定义了数据结构,

  • jquery html添加元素/删除元素操作实例详解

    本文实例讲述了jquery html添加元素/删除元素操作.分享给大家供大家参考,具体如下: 添加元素 添加新的 HTML 内容 将学习用于添加新内容的四个 jQuery 方法: append() - 在被选元素的结尾插入内容 prepend() - 在被选元素的开头插入内容 after() - 在被选元素之后插入内容 before() - 在被选元素之前插入内容 append() 方法 append() 方法在被选元素的结尾插入内容(仍然该元素的内部). $("p").append(

  • Java集合和数据结构排序实例详解

    目录 概念 插入排序 直接插入排序 代码实现 性能分析 希尔排序 代码实现 性能分析 选择排序 直接选择排序 代码实现 性能分析 堆排序 代码实现 性能分析 交换排序 冒泡排序 代码实现 性能分析 快速排序 代码实现 性能分析 非递归实现快速排序 代码实现 性能分析 归并排序 归并排序 代码实现 性能分析 非递归实现归并排序 代码实现 性能分析 海量数据的排序问题 总结 概念 排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作. 平时的上下文中,如果提到排序,通常

  • java中Iterator和ListIterator实例详解

    Iterator和ListIterator的作用范围以及关系: (1) Iterator可以用于迭接口List的实现ArrayList,LinkedList以及Map等. (2) ListIterator顾名思义,就是用于迭代List实现ArrayList,LinkedList. (3) 从源码或API文档中可以看出,Iterator为ListIterator的父类. public interface ListIterator<E> extends Iterator<E> { //

  • java集合框架线程同步代码详解

    List接口的大小可变数组的实现.实现了所有可选列表操作,并允许包括null在内的所有元素.除了实现List接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小.(此类大致上等同于Vector类,除了此类是不同步的.)size.isEmpty.get.set.iterator和listIterator操作都以固定时间运行.add操作以分摊的固定时间运行,也就是说,添加n个元素需要O(n)时间.其他所有操作都以线性时间运行(大体上讲).与用于LinkedList实现的常数因子相比,此实现的

  • 工作中Java集合的规范使用操作详解

    目录 一.前言 二.规范使用Java集合 一.前言 现代软件行业的高速发展对开发者的综合素质要求越来越高,因为不仅是编程知识点,其它维度的知识点也会影响到软件的最终交付质量.比如:五花八门的错误码会人为地增加排查问题的难度:数据库的表结构和索引设计缺陷带来的系统架构缺陷或性能风险:工程结构混乱导致后续项目维护艰难:没有鉴权的漏洞代码容易被黑客攻击等.依据约束力强弱及故障敏感性,规约依次分为[强制].[推荐].[参考]三大类.在延伸的信息中,“说明”对规约做了适当扩展和解释:“正例”提倡什么样的编

  • Java实现LRU缓存的实例详解

    Java实现LRU缓存的实例详解 1.Cache Cache对于代码系统的加速与优化具有极大的作用,对于码农来说是一个很熟悉的概念.可以说,你在内存中new 了一个一段空间(比方说数组,list)存放一些冗余的结果数据,并利用这些数据完成了以空间换时间的优化目的,你就已经使用了cache. 有服务级的缓存框架,如memcache,Redis等.其实,很多时候,我们在自己同一个服务内,或者单个进程内也需要缓存,例如,lucene就对搜索做了缓存,而无须依赖外界.那么,我们如何实现我们自己的缓存?还

  • java 线性表接口的实例详解

    java 线性表接口的实例详解 前言: 线性表是其组成元素间具有线性关系的一种线性结构,对线性表的基本操作主要有插入.删除.查找.替换等,这些操作可以在线性表的任何位置进行.线性表可以采用顺序存储结构和链式存储结构表示. 本接口的类属于dataStructure包的linearList子包.线性表接口LList声明如下,描述线性表的取值.置值.插入.删除等基本操作. package dataStructure.linearList; public interface LList<E> { bo

随机推荐