设计模式太难学?Java设计模式之迭代器模式

导读:本篇文章讲解 设计模式太难学?Java设计模式之迭代器模式,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com


前言

迭代器模式是行为型设计模式中的一种,它提供一个迭代器对象用来顺序访问集合对象内数据,而不用暴露集合对象内部细节。java当中用来遍历集合的Iterator迭代器就是迭代器设计模式的一种运用

一个集合对象最基本的功能应该就是提供存取以及查询能力。我们在使用一个集合对象时,最基本就是对集合对象进行存取或者遍历。使用迭代器模式时,会将集合对象拆分成存取和访问两个部分。存取元素由集合对象本身实现。引入一个迭代器对象,用来访问集合元素。

Java当中的集合对象就是采用迭代器模式设计的,例如: Collection、List、Set、Map 等都包含了迭代器。都是集合对象本身只负责存取,遍历集合则交给Iterator


一、迭代器模式

迭代器模式的结构角色如下:

  • 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合对象以及创建迭代器对象的接口。
  • 具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。
  • 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
  • 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。

结构图书(来源网络):
在这里插入图片描述

二、迭代器模式使用

我们自定义一个简单集合对象(元素存取使用List)来演示下迭代器模式的使用

定义抽象集合类

package com.example.study.iterator;

public interface Aggregate {

    public void add(Object obj);

    public void remove(Object obj);

    public Object get(Integer index);

    public Iterator getIterator();
}

迭代器抽象类

package com.example.study.iterator;

public interface Iterator {

    Object first();

    Object last();

    Object next();

    boolean hasNext();
}

具体集合实现类

package com.example.study.iterator;

import java.util.ArrayList;
import java.util.List;

public class AggregateImpl implements Aggregate{

    List<Object> objectList = new ArrayList<>();
    @Override
    public void add(Object obj) {
        objectList.add(obj);
    }

    @Override
    public void remove(Object obj) {
        objectList.remove(obj);
    }

    @Override
    public Object get(Integer index) {
        return objectList.get(index);
    }

    @Override
    public Iterator getIterator() {
        return new IteratorImpl(objectList);
    }
}

具体迭代器实现类

package com.example.study.iterator;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class IteratorImpl implements Iterator{

    private List<Object> objectList = null;

    private AtomicInteger index = new AtomicInteger(0);

    public IteratorImpl(List<Object> list) {
        this.objectList = list;
    }

    @Override
    public Object first() {
        if (objectList.size() > 0) return objectList.get(0);
        return null;
    }

    @Override
    public Object last() {
        return objectList.get(objectList.size()-1);
    }

    @Override
    public Object next() {
        Object obj = null;
        if (this.hasNext()) {
            obj = objectList.get(index.getAndAdd(1));
        }
        return obj;
    }

    @Override
    public boolean hasNext() {
        if (index.get() < objectList.size() - 1) {
            return true;
        }
        return false;
    }
}

客户端测试类

package com.example.study.iterator;

public class Client {

    public static void main(String[] args) {
        //自定义集合对象并添加元素
        Aggregate aggregate = new AggregateImpl();
        aggregate.add("周一");
        aggregate.add("周二");
        aggregate.add("周三");
        aggregate.add("周四");
        aggregate.add("周五");
        aggregate.add("周六");
        aggregate.add("周日");

        //使用自定义迭代器遍历集合对象
        CustomIterator iterator = aggregate.getIterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

    }
}

运行结果
在这里插入图片描述

以上示例,我们在访问集合对象时,直接使用自定义的迭代器去遍历集合。

迭代器模式还有一种使用方式:将迭代器对象作为集合类的内部类使用。Java当中的集合对象就是采取这种方式。以下举例:

抽象集合类以及抽象迭代器类保持不变,定义新的集合具体实现类,且定义具体迭代器类作为集合实现类的内部类

package com.example.study.iterator;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class AggregateExtImpl implements Aggregate{

    List<Object> objectList = new ArrayList<>();
    @Override
    public void add(Object obj) {
        objectList.add(obj);
    }

    @Override
    public void remove(Object obj) {
        objectList.remove(obj);
    }

    @Override
    public Object get(Integer index) {
        return objectList.get(index);
    }

    @Override
    public CustomIterator getIterator() {
        return new AggregateIt();
    }

    //迭代器对象作为集合对象内部类使用
    class AggregateIt implements CustomIterator {
        private AtomicInteger index = new AtomicInteger(0);
        @Override
        public Object first() {
            if (objectList.size() > 0) return objectList.get(0);
            return null;
        }

        @Override
        public Object last() {
            return objectList.get(objectList.size()-1);
        }

        @Override
        public Object next() {
            Object obj = null;
            if (this.hasNext()) {
                obj = objectList.get(index.getAndAdd(1));
            }
            return obj;
        }

        @Override
        public boolean hasNext() {
            if (index.get() < objectList.size() - 1) {
                return true;
            }
            return false;
        }
    }
}

客户端测试

package com.example.study.iterator;

public class Client {

    public static void main(String[] args) {
        //自定义集合对象(迭代器在集合对象内部)并添加元素
        Aggregate aggregate = new AggregateExtImpl();
        aggregate.add("周一");
        aggregate.add("周二");
        aggregate.add("周三");
        aggregate.add("周四");
        aggregate.add("周五");
        aggregate.add("周六");
        aggregate.add("周日");

        //使用自定义迭代器遍历集合对象
        CustomIterator iterator = aggregate.getIterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

    }
}

运行结果
在这里插入图片描述


总结

迭代器模式是通过将聚合对象的遍历行为分离出来,抽象成迭代器类来实现的,其目的是在不暴露聚合对象的内部结构的情况下,让外部代码透明地访问聚合的内部数据。

其主要优点如下。

  • 访问一个聚合对象的内容而无须暴露它的内部表示。
  • 遍历任务交由迭代器完成,这简化了聚合类。
  • 它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。
  • 增加新的聚合类和迭代器类都很方便,无须修改原有代码(看具体类结构设计)。
  • 封装性良好,为遍历不同的聚合结构提供一个统一的接口。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/99029.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!