我是靠谱客的博主 整齐人生,这篇文章主要介绍每日一类-手写ArrayList-迭代器-iterator,现在分享给大家,希望可以做个参考。

概述

        接着上一章:每日一类-手写ArrayList-泛型,本篇来讲下ArrayList的迭代器实现细节。因为篇幅所限,本篇先实现单向迭代方法iterator(),双向迭代listIterator()放到下一篇实现。

迭代器模式

        在讲iterator()  跟 ListIterator()之前,先来普及下iterator(迭代器)模式。   

        百度百科给出介绍:迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象(集合/数组)中的各种元素,而又不暴露该对象的内部表示。

类图

参与角色

Iterator:迭代器接口,定义迭代器操作规则, 一般有3个核心方法,

   1>hasNext() 判断是否可迭代  2>next() 执行迭代,返回当前元素 3>remove() 删除迭代到元素

ConcreteIterator:迭代器接口实现类,实现接口迭代3个方法。

Aggregate:抽象聚合对象,保存数据的集合对象。迭代器遍历元素的提供者,可以是抽象类有可以是接口。比如:List 接口 或者 AbstractList抽象类。

ConcreteAggregate:抽象聚合对象接口(抽象类)实现,由它调用iterator,实现元素逐一遍历。

以JDK为例:

迭代器-iterator

实现iterator() 方法,前提就应该建立起上面的迭代器模式结构:

MyIterator

/**
* 迭代器接口:定义迭代规则
*/
public interface MyIterator<E> {
/**
* 判断是否有下一个元素(判断是否可以迭代)
* @return
*/
boolean hasNext();
/**
* 获取当前迭代到元素(执行下一个迭代元素)
* @return
*/
E next();
/**
* 删除当前迭代到的元素
*/
void remove();
}

MyIterator 接口定义迭代器的规则,里面至少有迭代器的:hasNext,next, remove 3个核心方法。

操作示意图

 当执行next()时,cursor会自动往下移动

注意:还有另外一种理解方式:

游标所在位置在第一个元素前面,每移动一下,跳过一个元素。操作上个人认为其实没啥区别。 

MyItr 

定义在MyArrayList类内部,不对外暴露

public class MyArrayList<E> {
/**
* MyArrayList类内部定义私有内部类MyItr
* 目的:对应隐藏MyArrayList 的迭代器具体实现
*
MyArrayList 主要通过iterator方法暴露迭代接口即可。
*/
private class MyItr implements MyIterator<E>{
//游标(索引) 从0开始
private int cursor;
@Override
public boolean hasNext() {
//只要没迭代到最后,一直可迭代
return cursor != size;
}
@Override
public E next() {
//迭代时,如果游标超过总数,报错
if (cursor >= size)
throw new NoSuchElementException();
//++ 表示下次next就是下一个元素啦
return (E) elementData[cursor++];
}
@Override
public void remove() {
//以上来如果马上调用remove操作,而不先执行next,提示非法操作
if (cursor < 1){
throw new IllegalStateException("请先执行next方法");
}
//游标还是可操作范围内
if(cursor <= size){
//next 方法之后,游标执行带下一个元素,如果要删除,就删除当前元素
//游标回归上一个值
MyArrayList.this.remove(cursor -1);
//删除之后,集合中的size-1,右边也应该同步-1
cursor--;
}
}
}
}

 在MyArrayList类中定义iterator方法,提供迭代器的操作对象,用于迭代

public class MyArrayList<E> {
.....
/**
* 对外暴露迭代器方法,用于操作集合迭代器
* 注意,此处使用接口多态,有效隐藏掉MyItr私有内部类实现细节
* @return
*/
public MyIterator<E> iterator(){
return new MyItr();
}
....
}

迭代测试

public class App{
public static void main(String[] args) {
MyArrayList<String> list = new MyArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
MyIterator<String> iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(list);
iterator.next();
iterator.remove();
System.out.println(list);
}
}
}

为了打印好看,重写toString方法


public String toString() {
MyIterator<E> it = iterator();
if (! it.hasNext()){
return "[]";
}
StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
E e = it.next();
sb.append(e);
if (! it.hasNext()){
return sb.append(']').toString();
}
sb.append(',').append(' ');
}
}
[a, b, c, d]
[b, c, d]
[b, c, d]
[c, d]
[c, d]
[d]
[d]
[]

到这,MyArrayList类的迭代器功能就是实现了。

最后

以上就是整齐人生最近收集整理的关于每日一类-手写ArrayList-迭代器-iterator的全部内容,更多相关每日一类-手写ArrayList-迭代器-iterator内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(59)

评论列表共有 0 条评论

立即
投稿
返回
顶部