前言
本文主要会介绍迭代器模式的原理,并会结合示例进行分析。迭代器模式其实我们基本上每个人都在用,可能只是自己没有察觉到这就是迭代器模式,等我们介绍完了大家就明白了,迭代器模式比较容易理解,而且一般应用开发使用的比较少,但是在底层的代码应用非常广泛
什么是迭代器模式
迭代器模式(Iterator Pattern)又称为游标者模式(Cursor Pattern)。迭代器模式提供了一种顺序访问集合/容器中对象元素的方法,而又无需暴露集合内部表示。
迭代器模式可以为不同额容器提供一致的遍历行为,而且不用关心内部元素的组成结构,属于行为型模式。
迭代器模式的本质就是抽离集合对象迭代行为到迭代容器中,并提供统一的访问接口。
迭代器模式示例
好了,装逼时刻又到了:Talk is cheap,Show you the code,先看一个非常简单的例子。
我们以传送行李为例子来写一个示例:
1、首先新建一个集合的元素类:
package com.zwx.design.pattern.iterator;
/**
* 遍历元素-行李
*/
public class Baggage {
private String name;
public Baggage(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2、新建一个迭代器接口:
package com.zwx.design.pattern.iterator;
public interface IMyIterator<E> {
E next();
boolean hasNext();
}
3、新建一个具体的迭代器来实现迭代接口:
package com.zwx.design.pattern.iterator;
import java.util.List;
public class MyIteratorImpl<E> implements IMyIterator<E> {
private List<E> list;
private int cursor;
private E element;
private int size;
public MyIteratorImpl(List<E> list) {
this.list = list;
this.size = list.size();
}
@Override
public E next() {
E element = list.get(cursor);
cursor++;
return element;
}
@Override
public boolean hasNext() {
return cursor != size;
}
}
4、接下来就该建立我们的集合接口了:
package com.zwx.design.pattern.iterator;
import java.util.ArrayList;
public interface IBaggageAggregate {
void add(Baggage baggage);
void remove(Baggage baggage);
int size();
IMyIterator<Baggage> iterator();
}
5、然后再新建一个具体的集合实现类:
package com.zwx.design.pattern.iterator;
import java.util.ArrayList;
import java.util.List;
public class BaggageAggregateImpl implements IBaggageAggregate {
private List list;
public BaggageAggregateImpl() {
this.list = new ArrayList<>();
}
@Override
public void add(Baggage baggage) {
list.add(baggage);
}
@Override
public void remove(Baggage baggage) {
list.remove(baggage);
}
@Override
public int size() {
return list.size();
}
@Override
public IMyIterator<Baggage> iterator() {
return new MyIteratorImpl<Baggage>(list);
}
}
6、最后让我们写一个测试类来测试一下迭代:
package com.zwx.design.pattern.iterator;
import java.util.ArrayList;
import java.util.List;
public class TestIterator {
public static void main(String[] args) {
IBaggageAggregate iBaggageAggregate = initBaggage();
System.out.println("当前对象元素个数为:" + iBaggageAggregate.size() + "个");
IMyIterator<Baggage> it = iBaggageAggregate.iterator();
while (it.hasNext()){
Baggage baggage = it.next();
System.out.println(baggage.getName());
}
}
private static IBaggageAggregate initBaggage() {
IBaggageAggregate iBaggageAggregate = new BaggageAggregateImpl();
for (int i=0;i<10;i++){
Baggage box = new Baggage("箱子" + (i+1));
iBaggageAggregate.add(box);
}
return iBaggageAggregate;
}
}
运行之后输出如下结果:
当前对象元素个数为:10个
箱子1
箱子2
箱子3
箱子4
箱子5
箱子6
箱子7
箱子8
箱子9
箱子10
看完这个例子其实大家心里应该很明确了,这不就是集合的迭代吗?确实是的,所以我们一开始才说了迭代器模式我们自己开发很少用,因为基本上用到的数据结构自身都提供了迭代器,我们没必要去重复造轮子。除非我们自己去定义新的数据结构,而且数据结构相对复杂那是可以自己定义一个迭代器来进行迭代的。
迭代器模式角色
从上面示例中,我们可以得出迭代器模式主要有4个角色:
- 抽象迭代器(Iterator):抽象迭代器负责定义访问和遍历元素的接口(如示例中的IMyIterator)。
- 具体迭代器(ConcreteIterator):提供具体元素的遍历行为(如示例中的MyIteratorImpl)。
- 抽象容器(Aggregate):负责定义提供具体迭代器的接口(如示例中的IBaggageAggregate,类似于集合中的List)。
- 具体容器(ConcreteAggregate):创建具体的迭代器(如示例中的BaggageAggregateImpl,类似于集合中的ArrayList)。
迭代器模式在JDK源码中应用
这个其实都不需要在这里去举例子了,比如说List中的Iterator,Map中的EntryIterator等等这些我们天天使用的就是迭代器模式的体现了。
迭代器模式适用场景
迭代器模式在生活中有一个基本上大家都经历过场景,那就是机场,火车站和地铁站的传送带,我们根本不需要关系容器内部(行李内部)的具体结构,只需要将行李逐个传送到目的地就行。迭代器模式主要适用于以下场景:
- 1、访问一个集合对象的内容而不想暴露它的内部表示。
- 2、为遍历不同的集合提供一个统一的访问接口
迭代器模式优缺点
优点:
- 1、解耦了迭代与集合。迭代器模式封装具体的迭代算法,即使迭代器内部算法发生变化,也不会影响到原有的集合对象。
- 2、简化了集合对象接口。迭代器模式将集合对象本身应该提供的元素迭代接口放到了迭代器中,使得集合对象可以无需关心具体的迭代行为。
- 3、多态迭代。迭代器模式为不同聚合结构的集合提供了一致的遍历接口,即一个迭代器可以用来迭代不同的集合对象。
- 4、元素迭代功能的多样化。每个集合可以提供一个或者多个不同功能的迭代器,使得同种元素可以有不同的迭代行为。
缺点
- 1、迭代器模式如果用于简单的数据结构(如数组或者链表)时,反而会使得迭代元素方式变得更加繁琐复杂化。
总结
本文主要介绍了迭代器模式的基本使用,并通过一个简单的示例来帮助更好的理解迭代器模式,最后介绍了迭代器模式在相关JDK源码中的体现。
请关注我,和孤狼一起学习进步。