IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> ArrayList源码分析—迭代器 -> 正文阅读

[Java知识库]ArrayList源码分析—迭代器

迭代器

ArrayList的迭代器

案例一:

已知集合 List 泛型是String
里面有三个元素 ,迭代器遍历获取

//操作  Iterator iterator = arrayList1.iterator()
//      while ( iterator.hasNext() ) {
//          System.out.println(iterator.next());
//      }

public Iterator<E> iterator() {
    // 内部类
    return new Itr();
}


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() {}
    
    // 是否有下一个元素
    public boolean hasNext() {
        // 当前光标是不是等于size大小
        return cursor != size;
    }
    
    // next方法
    @SuppressWarnings("unchecked")
    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];
    }
    
    // 校验预期修改集合次数是否和实际修改集合次数一样
    final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }
    
    ...其他方法...
}


案例二

集合中有 hello java PHP 三个字符串
在迭代器迭代时判断
如果时PHP 就 list.remove删除掉PHP

// add方法
public boolean add(E e) {
   // 在这里  修改了modCount   集合修改次数
   // 案例中所有的add执行完  = 3
   ensureCapacityInternal(size + 1);  // Increments modCount!!
   elementData[size++] = e;
   return true;
}

// remove方法
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 void fastRemove(int index) {
   // 实际修改次数会变化
   modCount++;
   int numMoved = size - index - 1;
   if (numMoved > 0)
       System.arraycopy(elementData, index+1, elementData, index,
                        numMoved);
   // 尽快被垃圾回收
   elementData[--size] = null; // clear to let GC do its work
}


public Iterator<E> iterator() {
   // 内部类
   return new Itr();
}


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
   // 将集合的修改次数  赋值给 预期修改次数
   // 获取到迭代器的时候  expectModeCount = modCount = 3
   int expectedModCount = modCount;

   Itr() {}
   
   // 是否有下一个元素
   // 在删除掉一个元素后 集合的大小被修改为了2  这个时候是不相等的!!!!!!!!!
   // 所以会再执行一次next方法 这次就会引发异常
   public boolean hasNext() {
       // 当前光标是不是等于size大小
       return cursor != size;
   }
   
   // next方法
   @SuppressWarnings("unchecked")
   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];
   }
   
   // 校验预期修改集合次数是否和实际修改集合次数一样
   final void checkForComodification() {
       if (modCount != expectedModCount)
           throw new ConcurrentModificationException();
   }
   
   ...方法...
}

// 结论
// 集合调用add时  实际修改次数 那个变量  会+1
// 获取迭代器时  预期修改次数  被赋值  一次
// 删除元素后  就会引发并发修改异常

案例三

集合中有 hello PHP java 三个字符串
在迭代器迭代时判断
如果时PHP 就 list.remove删除掉PHP
PHP在倒数第二个的位置

// 正常添加结束
// 要删除的元素在集合的倒数第二个位置时不会产生异常
// 原因时在调用hasNext时 光标的值和集合的长度一样
// 不会调用next方法
// 底层就不会产生并发修改异常
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-30 08:33:07  更:2022-04-30 08:35:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:53:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码