迭代器修改元素_迭代器模式

7028be48fc48bb9132e2deed04973647.png

本文转自“雨夜随笔”公众号,欢迎关注

迭代器模式​mp.weixin.qq.com
93e254c1a2cd5634883c5929754c7d18.png

在代码中,我们会用到各种各样的List或者Map。他们提供了一种方式来存储和查找数据,而在他们的背后都隐藏的迭代器模式的思想。

意图

迭代器模式是行为型模式的一种,设计的意图就是在不暴露数据表现形式(列表,栈或者树等)的情况下遍历集合中的所有元素。

fd16d7a41d166497697d32e94fc59aac.png

问题

在代码中,我们无可避免的需要面对数据。而数据就需要相应的存储容器,而在各式各样的容器中,集合就是其中最为常用的数据类型之一。

1d2b1d69a99ac06f9d73ada73dd3353a.png

集合既可以使用简单的列表来存储元素,也可以用栈、树、图或者其他数据结构来存储。

无论集合是采用什么数据结构来存储数据,都必须提供对其存储元素的访问方式。因为我们存储的数据最终还是要被使用的,不然就没有任何价值。所以集合需要提供一种遍历元素的方式,并且保证遍历的过程不会访问到重复的元素。

这个说起来也很简单,因为如果我们的集合基于列表,那么我们可以很方便的通过内存来进行读取。但是如果是基于复杂的数据结构呢?比如说树,就有前序遍历,后序遍历和中序遍历。并且随着需求的改变,我们可以需要通过别的方式进行遍历。

10535d3f7caf63e18e805d3a2eba89e9.png

所以说,我们不能一有需求改动,就重新实现一遍遍历算法然后加入到集合对象的方法中。

同时我们如果没有一种通用的方式来解耦集合,那么我们的代码将不得不与特定集合类进行耦合。

解决方法

那么面对上面的问题,我们可以尝试将集合的遍历方式进行抽象,将遍历行为抽取为单独的迭代器对象。通过这种方式,我们只需要定义好迭代器的接口,这样当我们需要新的遍历方法,我们只需要定义一个新的迭代器对象,然后再客户端中引入就可以了。

那么我们现在的就是对遍历方式来进行抽象,来满足我们实际的业务需要。

// 方式1
public interface Iterator<E> {
    boolean hasNext(); // 容器内是否有下一个元素
    void next(); // 移动遍历位置
    E currentItem(); // 当前指向的元素
}

// 方式2
public interface Iterator<E> {
    boolean hasNext(); // 容器内是否有下一个元素
    E next(); // 获取指向的元素并移动遍历位置
}

这两种方式的区别在于:

  • 第一种方式的定义更加灵活,因为我们可以在不移动游标的情况下查询当前元素。
  • 第二种方式更适合遍历场景,这种可以减少复杂度。

代码实现

import java.util.ArrayList;

public class ListIterator {
    // 内部存储
    private ArrayList<Integer> mValues = new ArrayList<>();
    // 当前索引
    private Integer mCurrentItem = 0;

    // 这里只是简单的展示,实际上的要更复杂
    // 要考虑遍历过程中增加元素的问题
    // 我们将在实战中详细说明
    public void addItem(int value){
        mValues.add(value);
    }

    // 是否有下一个元素
    public boolean hasNext(){
        if(mCurrentItem + 1 <= mValues.size()){
            return true;
        }
        return false;
    }

    // 索引后移
    public void next(){
        if(hasNext()){
            mCurrentItem++;
        } else {
            throw new IndexOutOfBoundsException("no next value");
        }
    }

    // 获取当前元素
    public int currentItem(){
        return mValues.get(mCurrentItem);
    }
}

使用起来也很方便

public class Application {
    public static void main(String[] args){
        ListIterator iterator = new ListIterator();
        iterator.addItem(1);
        iterator.addItem(2);
        iterator.addItem(3);
        for(; iterator.hasNext(); iterator.next()){
            System.out.printf("%d ", iterator.currentItem());
        }
    }
}

// 输出:1 2 3

总结

迭代器模式是行为型设计模式的一种,主要是为了关注集合类对象和使用者之间的交互。通过抽象集合类的遍历行为,来成功解耦使用者和集合类对象。

迭代器模式的设计思想就是抽象集合类对象的遍历行为,然后屏蔽集合类的内部存储结构和解决不同遍历行为的差异。通过迭代器模式我们可以在对集合进行不同形式的遍历时,最小化减少客户端和集合类的修改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值