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

Java Iterator接口实现代码解析

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

Java Iterator接口实现代码解析

Iterator接口

源代码

package java.util;

import java.util.function.Consumer;


public interface Iterator {
  
  boolean hasNext();

  
  E next();

  
  default void remove() {
    throw new UnsupportedOperationException("remove");
  }

  
  default void forEachRemaining(Consumer action) {
    Objects.requireNonNull(action);
    while (hasNext())
      action.accept(next());
  }
}

阅读笔记

1. Iterator接口与Enumeration接口的关系/Iterator接口在Java集合库中的作用

Iterator接口是Java集合框架的一部分,被用于替代原有的Enumeration接口。(“Iterator”比“Enumeration”更简短、表意更清晰、功能更多,具体的信息下面Enumeration接口的注解中说的挺清楚,且Enumeration注解中也建议编程人员改用Iterator接口)

Java类库中,集合类的基本接口是Collection接口,而Collection接口实现了Iterable接口,Iterable接口中有一个iterator()方法用于获取Iterator对象。

package java.util;


public interface Enumeration {
  
  boolean hasMoreElements();

  
  E nextElement();
}

2.hasNext()、next()、remove()方法的关系

hasNext()方法:判断是否还有元素可以进行迭代;

next()方法:迭代元素;

remove()方法:


public static void main(String[] args) {
    Collection stringCollection = new ArrayList<>();
    stringCollection.add("Hello");
    stringCollection.add("World");
    stringCollection.add("!");
    Iterator stringIterator = stringCollection.iterator();

    stringIterator.next();
    stringIterator.remove();//OK
  }
public static void main(String[] args) {
    ......
    stringIterator.next();
    stringCollection.add("abc");//基本集合被改变
    stringIterator.remove();//ERROR - java.util.ConcurrentModificationException
  }
public static void main(String[] args) {
    ......
    stringIterator.next();
    stringCollection.add("abc");//基本集合被改变
    stringIterator.next();//ERROR - java.util.ConcurrentModificationException
  }
public static void main(String[] args) {
    ......
    stringIterator.next();
    stringCollection.add("abc");//基本集合改变
    stringIterator = stringCollection.iterator();//重新获取迭代器
    stringIterator.next();//OK
    stringIterator.remove();//OK
  }

三者关系:调用remove()方法前必须先调用next()方法,调用next()方法前最好先调用hasNext()方法。

3.具体实现类

AbstractList类中定义了一个实现了Iterator接口的内部类:

private class Itr implements Iterator {
  
  int cursor = 0;

  
  int lastRet = -1;

  
  int expectedModCount = modCount;

  public boolean hasNext() {
    return cursor != size();
  }

  public E next() {
    checkForComodification();
    try {
      int i = cursor;
      E next = get(i);
      lastRet = i;//最近一次调用next()方法返回的元素的下标。
      cursor = i + 1;//下一次调用next()方法返回的元素的下标。
      return next;
    } catch (IndexOutOfBoundsException e) {
      checkForComodification();
      throw new NoSuchElementException();
    }
  }

  public void remove() {
    if (lastRet < 0)
      throw new IllegalStateException();//所以,调用remove()前必须先调用next()
    checkForComodification();

    try {
      AbstractList.this.remove(lastRet);
      if (lastRet < cursor)
 cursor--;//因为移除了一个元素
      lastRet = -1;//所以,不能连续调用两次remove()方法
      expectedModCount = modCount;
    } catch (IndexOutOfBoundsException e) {
      throw new ConcurrentModificationException();
    }
  }

  final void checkForComodification() {
    if (modCount != expectedModCount)
      throw new ConcurrentModificationException();
  }
}

看完上面的代码,我对modCount、expectedModCount变量以及checkForComodification()方法的作用比较好奇,所以尝试着去搞清楚。

先来看modeCount变量,这个变量被声明在内部类的外部:

public abstract class AbstractList extends AbstractCollection implements List {
  
  protected transient int modCount = 0;
}

看完上面的源码注解,已经大概能够知道modCount、expectedModCount以及checkForComodification()的作用了。

假如把基础集合当作一个银行账号,基础集合中的元素表示存款。那么modCount就相当于银行为每个账号做的消费记录,expectedModCount就相当于是账号持有人自己做的一份消费记录,一般银行和账号持有人自己做的消费记录都不会出错。

final void checkForComodification() {
  if (modCount != expectedModCount)
    throw new ConcurrentModificationException();
}

一旦银行那边的消费记录和自己手里的那份消费记录对不上,肯定是账号被盗用了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/134237.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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