欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Iterator-Java

程序员文章站 2023-02-02 10:41:22
在Java中,Iterator的作用就是为了方便处理集合中的元素。例如获取和删除集合中的元素。 在JDK8,Iterator接口提供了如下方法: 迭代器Iterator最基本的两个方法是next()和hasNext()。其中Java迭代器多了一个remove()方法。在JDK8中又新增了forEac ......

在java中,iterator的作用就是为了方便处理集合中的元素。例如获取和删除集合中的元素。

在jdk8,iterator接口提供了如下方法:

Iterator-Java

迭代器iterator最基本的两个方法是next()和hasnext()。其中java迭代器多了一个remove()方法。在jdk8中又新增了foreachremaining()方法。

接下来,以arraylist为例,看下迭代器在java中的实现。

在arraylist中,以内部类的方式实现,每次调用iterator()方法,都会new itr()。

先看一下arraylist迭代器的实现类:

Iterator-Java

定义的参数如下:

1 int cursor;       // 下标,默认值0;
2 int lastret = -1; //最后一个元素的下标,如果没有返回-1;
3 int expectedmodcount = modcount;//结构修改(添加、删除等操作)次数,默认值0;

定义的方法如下:

hasnext()方法: 

1  public boolean hasnext() {
2      return cursor != size;
3 }

当集合中不存在下一个元素,即已经遍历至集合末尾时,该方法返回false。hasnext 方法主要用于循环终止条件。

next()方法:

 1 public e next() {
 2     checkforcomodification();
 3     int i = cursor;
 4     if (i >= size)
 5         throw new nosuchelementexception();
 6     object[] elementdata = arraylist.this.elementdata;
 7     if (i >= elementdata.length)
 8         throw new concurrentmodificationexception();
 9     cursor = i + 1;
10     return (e) elementdata[lastret = i];
11 }

在执行next()方法时,会先执行checkforcomodification()方法,做一个判断(检查所迭代的列表对象是否被修改过):

1 final void checkforcomodification() {
2     if (modcount != expectedmodcount) throw new concurrentmodificationexception();
3 }

在对集合进行迭代过程中,不允许出现迭代器以外的对元素的操作,因为这样会产生安全隐患,java会抛出异常并发修改异常(concurrentmodificationexception),普通迭代器只支持在迭代过程中的删除动作。

如果在遍历arraylist时,想添加元素和修改元素,可以调用list集合的特有迭代器listiterator。

remove()方法:

 1 public void remove() {
 2     if (lastret < 0) throw new illegalstateexception();
 3     checkforcomodification();
 4 
 5     try {
 6         arraylist.this.remove(lastret);
 7         cursor = lastret;
 8         lastret = -1;
 9         expectedmodcount = modcount;
10     } catch (indexoutofboundsexception ex) {
11         throw new concurrentmodificationexception();
12     }
13 }

java普通迭代器中唯一支持修改结构的操作。在执行完删除操作后,会更新expectedmodcount字段的值。

foreachremaining()方法:

 1 public void foreachremaining(consumer<? super e> consumer) {
 2     objects.requirenonnull(consumer);
 3     final int size = arraylist.this.size;
 4     int i = cursor;
 5     if (i >= size) {
 6         return;
 7     }
 8     final object[] elementdata = arraylist.this.elementdata;
 9     if (i >= elementdata.length) {
10         throw new concurrentmodificationexception();
11     }
12     while (i != size && modcount == expectedmodcount) {
13         consumer.accept((e) elementdata[i++]);
14     }
15     // update once at end of iteration to reduce heap write traffic
16     cursor = i;
17     lastret = i - 1;
18     checkforcomodification();
19 }

foreachremaining()是jdk8中新增的方法。foreachremaining()使用迭代器iterator的所有元素,并且第二次调用它将不会做任何事情,因为不再有下一个元素。

一个使用场景:获得对应集合的迭代器iterator,然后您可以开始迭代,next()直到达到某个条件,然后使用foreachremaining()操作该iterator上的其余部分。

接下来,看一下刚才提到的listiterator。

在普通的iterator中,只能对元素进行获取(next())和删除(remove())的操作。而listiterator提供了更多的方法:

Iterator-Java

add(e e): 将指定的元素插入列表,插入位置为迭代器当前位置之前
hasnext():以正向遍历列表时,如果列表迭代器后面还有元素,则返回 true,否则返回false
hasprevious():如果以逆向遍历列表,列表迭代器前面还有元素,则返回 true,否则返回false
next():返回列表中listiterator指向位置后面的元素
nextindex():返回列表中listiterator所需位置后面元素的索引
previous():返回列表中listiterator指向位置前面的元素
previousindex():返回列表中listiterator所需位置前面元素的索引

在使用特有的迭代器时,我们就能做更多的操作了。