JAVA 集合类的认识(1)—— Iterator 迭代器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/AnselLyy/article/details/81056119

Iterator

JAVA 集合主要分为两类:Collection 和 Map. 而 Collection 又继承了 Iterable 接口,Iterable 接口内只有一个 iterator 方法,返回一个 Iterator 迭代器

public interface Iterable<T> {

    /**
    * Returns an {@link Iterator} for the elements in this object.
    *
    * @return An {@code Iterator} instance.
    */
    Iterator<T> iterator();

}

关于 Enumeration

  • hasMoreElements() //是否还有元素
  • nextElement() //返回下一个元素

Enumeration 接口早在 JDK 1.0 时就推出了,当时比较早的容器比如 Hashtable, Vector 都使用它作为遍历工具;
在 JDK 1.2 后,Iterator 替代了它的功能;
Iterator adds an optional remove operation, and has shorter method names

ConcurrentModificationException

  • 当迭代器在调用 next、remove 方法时,会比较 expectedModCount 和 modCount 是否相等
  • modCount 在每次 add、clear、remove 时都会修改
  • 如果不相等,则抛出 ConcurrentModificationException,也就是 Fail-Fast 机制

modCount 和 expectedModCount

  • modCount,记录了集合结构性变化的次数
  • expectedModCount 的初值为 modCount
  • hasNext 的判断条件为 cursor != size,就是当前迭代的位置不是数组的最大容量值就返回 true
  • next 和 remove 操作之前都会先调用 checkForComodification 来检查 expectedModCount 和 modCount 是否相等

Fail-Fast 机制

java.util.HashMap、java.util.ArrayList 不是线程安全的,因此如果在使用迭代器的过程中有其他线程修改了 map 或 list,那么将抛出 ConcurrentModificationException,这就是所谓 fail-fast 策略。这一策略在源码中的实现是通过 modCount 域,modCount 顾名思义就是修改次数,对 map 或 list 内容的修改都将增加这个值,那么在迭代器初始化过程中会将这个值赋给迭代器的 expectedModCount。在迭代过程中,判断 modCount 跟 expectedModCount 是否相等。

解决方案

  • 方法一:用 CopyOnWriteArrayList,ConcurrentHashMap 替换 ArrayList, HashMap,它们的功能和名字一样,在写入时会创建一个 copy,然后在这个 copy 版本上进行修改操作,这样就不会影响原来的迭代。不过坏处就是浪费内存。
  • 方法二:使用 Collections.synchronizedList 加 同步锁

Iterator 使用方法

所有 Collection 的子类都有 iterator() 方法来获得 Iterator,通过 Iterator 的标准操作方法,可以让我们不必关心具体集合的类型,从而避免向客户端暴露出集合的内部结构。

  • 不使用 Iterator 遍历集合是这样的:
for (int i = 0; i < size; i++) {
    // ...
}
  • 使用 Iterator 遍历集合是这样的:
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

对比而言,后者客户端代码与具体集合类型耦合性弱,复用性更强。缺点就是无法获取指定的元素,只能挨个遍历。

猜你喜欢

转载自blog.csdn.net/AnselLyy/article/details/81056119