栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

ArrayList源码分析—迭代器

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ArrayList源码分析—迭代器

迭代器

ArrayList的迭代器

案例一:

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

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

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


private class Itr implements Iterator {
    // 迭代器的光标
    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 iterator() {
   // 内部类
   return new Itr();
}


private class Itr implements Iterator {
   // 迭代器的光标
   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方法
// 底层就不会产生并发修改异常
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/842334.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号