Iterator 迭代器
意图
提供一种方法顺序访问一个聚合对象中各个元素 , 而又不需暴露该对象的内部表示。
动机
一个聚合对象, 如列表(list), 应该提供一种方法来让别人可以访问它的元素,而又不需暴露它的内部结构
迭代器类定义了一个访问该列表元素的接口。迭代器对象负责跟踪当前的元素 ;即, 它知道哪些元素已经遍历过了。
适用性
- 访问一个聚合对象的内容而无需暴露它的内部表示。
- 支持对聚合对象的多种遍历。
- 为遍历不同的聚合结构提供一个统一的接口 (即, 支持多态迭代)。
结构
定义一个抽象列表类AbstractList,它提供操作列表的公共接口。类似地,我们也需要一个抽象的迭代器类Iterator,它定义公共的迭代接口。然后我们可以为每个不同的列表实现定义具体的Iterator子类。这样迭代机制就与具体的聚合类无关了。
参与者
Iterator:迭代器定义访问和遍历元素的接口。
ConcreteIterator:具体迭代器实现迭代器接口;对该聚合遍历时跟踪当前位置。
Aggregate:聚合定义创建相应迭代器对象的接口。
ConcreteAggregate:具体聚合实现创建相应迭代器的接口,该操作返回ConcreteAggregate的一个适当的实例。
效果
- 访问一个聚合对象的内容而无需暴露它的内部表示;
- 支持对聚合对象的多种遍历(从前到后,从后到前);
- 为遍历不同的聚合结构提供一个统一的接口,即支持多态迭代。
实现
#include <iostream>
using namespace std; typedef struct tagNode
{
int value;
tagNode *pNext;
}Node; class JTList
{
public:
JTList() : m_pHead(NULL), m_pTail(NULL){};
JTList(const JTList &);
~JTList();
JTList &operator=(const JTList &); long GetCount() const;
Node *Get(const long index) const;
Node *First() const;
Node *Last() const;
bool Includes(const int &) const; void Append(const int &);
void Remove(Node *pNode);
void RemoveAll(); private:
Node *m_pHead;
Node *m_pTail;
long m_lCount;
}; class Iterator
{
public:
virtual void First() = ;
virtual void Next() = ;
virtual bool IsDone() const = ;
virtual Node *CurrentItem() const = ;
}; class JTListIterator : public Iterator
{
public:
JTListIterator(JTList *pList) : m_pJTList(pList), m_pCurrent(NULL){} virtual void First();
virtual void Next();
virtual bool IsDone() const;
virtual Node *CurrentItem() const; private:
JTList *m_pJTList;
Node *m_pCurrent;
}; JTList::~JTList()
{
Node *pCurrent = m_pHead;
Node *pNextNode = NULL;
while (pCurrent)
{
pNextNode = pCurrent->pNext;
delete pCurrent;
pCurrent = pNextNode;
}
} long JTList::GetCount()const
{
return m_lCount;
} Node *JTList::Get(const long index) const
{
// The min index is 0, max index is count - 1
if (index > m_lCount - || index < )
{
return NULL;
} int iPosTemp = ;
Node *pNodeTemp = m_pHead;
while (pNodeTemp)
{
if (index == iPosTemp++)
{
return pNodeTemp;
}
pNodeTemp = pNodeTemp->pNext;
}
return NULL;
} Node *JTList::First() const
{
return m_pHead;
} Node *JTList::Last() const
{
return m_pTail;
} bool JTList::Includes(const int &value) const
{
Node *pNodeTemp = m_pHead;
while (pNodeTemp)
{
if (value == pNodeTemp->value)
{
return true;
}
pNodeTemp = pNodeTemp->pNext;
}
return false;
} void JTList::Append(const int &value)
{
// Create the new node
Node *pInsertNode = new Node;
pInsertNode->value = value;
pInsertNode->pNext = NULL; // This list is empty
if (m_pHead == NULL)
{
m_pHead = m_pTail = pInsertNode;
}
else
{
m_pTail->pNext = pInsertNode;
m_pTail = pInsertNode;
}
++m_lCount;
} void JTList::Remove(Node *pNode)
{
if (pNode == NULL || m_pHead == NULL || m_pTail == NULL)
{
return;
} if (pNode == m_pHead) // If the deleting node is head node
{
Node *pNewHead = m_pHead->pNext;
m_pHead = pNewHead;
}
else
{
// To get the deleting node's previous node
Node *pPreviousNode = NULL;
Node *pCurrentNode = m_pHead;
while (pCurrentNode)
{
pPreviousNode = pCurrentNode;
pCurrentNode = pCurrentNode->pNext;
if (pCurrentNode == pNode)
{
break;
}
} // To get the deleting node's next node
Node *pNextNode = pNode->pNext; // If pNextNode is NULL, it means the deleting node is the tail node, we should change the m_pTail pointer
if (pNextNode == NULL)
{
m_pTail = pPreviousNode;
} // Relink the list
pPreviousNode->pNext = pNextNode;
} // Delete the node
delete pNode;
pNode = NULL;
--m_lCount;
} void JTList::RemoveAll()
{
delete this;
} void JTListIterator::First()
{
m_pCurrent = m_pJTList->First();
} void JTListIterator::Next()
{
m_pCurrent = m_pCurrent->pNext;
} bool JTListIterator::IsDone() const
{
return m_pCurrent == m_pJTList->Last()->pNext;
} Node *JTListIterator::CurrentItem() const
{
return m_pCurrent;
} int main()
{
JTList *pJTList = new JTList;
pJTList->Append();
pJTList->Append();
pJTList->Append();
pJTList->Append();
pJTList->Append();
pJTList->Append();
pJTList->Append();
pJTList->Append();
pJTList->Append();
pJTList->Append(); Iterator *pIterator = new JTListIterator(pJTList); // Print the list by JTListIterator
for (pIterator->First(); !pIterator->IsDone(); pIterator->Next())
{
cout << pIterator->CurrentItem()->value << "->";
}
cout << "NULL" << endl; // Test for removing
Node *pDeleteNode = NULL;
for (pIterator->First(); !pIterator->IsDone(); pIterator->Next())
{
pDeleteNode = pIterator->CurrentItem();
if (pDeleteNode->value == )
{
pJTList->Remove(pDeleteNode);
break;
}
} // Print the list by JTListIterator
for (pIterator->First(); !pIterator->IsDone(); pIterator->Next())
{
cout << pIterator->CurrentItem()->value << "->";
}
cout << "NULL" << endl; delete pIterator;
delete pJTList; return ;
}
Iterator 迭代器的更多相关文章
- ES6笔记(6)-- Set、Map结构和Iterator迭代器
系列文章 -- ES6笔记系列 搞ES6的人也是够无聊,把JS弄得越来越像Java.C++,连Iterator迭代器.Set集合.Map结构都出来了,不知道说什么好... 一.简单使用 1. iter ...
- vector容器+iterator迭代器
关于vector容器的详细描述,可参考:http://www.jb51.net/article/41648.htm 关于iterator迭代器的描述,可参考http://www.cppblog.c ...
- C++ Iterator迭代器介绍及Iterator迭代器用法代码举例
C++ Iterator迭代器介绍 迭代器可被用来访问一个容器类的所包函的全部元素,其行为像一个指针.举一个例子,你可用一个迭代器来实现对vector容器中所含元素的遍历.有这么几种迭代器如下: 迭代 ...
- 【转】Java学习之Iterator(迭代器)的一般用法 (转)
[转]Java学习之Iterator(迭代器)的一般用法 (转) 迭代器(Iterator) 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭 ...
- 设计模式(十五):Iterator迭代器模式 -- 行为型模式
1.概述 类中的面向对象编程封装应用逻辑.类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态.单独的对象是一种组织代码的有用方法,但通常你会处理一组对象或者集合. 集合不一定是均一的.图形用 ...
- C#:iterator 迭代器/partial class 分布类/泛型
C#:iterator 迭代器/partial class 分布类/泛型 iterator 迭代器 写个最简单的迭代,(迭代一个字符串数组): 1.实现接口中的方法: 1 using System; ...
- [设计模式] Iterator - 迭代器模式:由一份奥利奥早餐联想到的设计模式
Iterator - 迭代器模式 目录 前言 回顾 UML 类图 代码分析 抽象的 UML 类图 思考 前言 这是一包奥利奥(数组),里面藏了很多块奥利奥饼干(数组中的元素),我将它们放在一个碟子上慢 ...
- Python 中 Iterator(迭代器)和Iterable(迭代对象)的区别
直接可以用作for循环的数据类型有以下几种: tuple.list.dict.str等, 上述数据类型可以用作for循环的叫做可迭代对象Iterable.可以使用isinstance判断一个对象是否是 ...
- 使用Iterator迭代器循环集合
1.Iterator迭代器用于遍历集合元素,获取迭代器可以使用. 2.Iterator提供了统一遍历集合元素的 方式 ,其提供了用于遍历集合的连个方法----- boolean hasNext()判 ...
- [C# 设计模式] Iterator - 迭代器模式:我与一份奥利奥早餐的故事
Iterator - 迭代器模式 目录 前言 回顾 UML 类图 代码分析 抽象的 UML 类图 思考 前言 这是一包奥利奥(数组),里面藏了很多块奥利奥饼干(数组中的元素),我将它们放在一个碟子上慢 ...
随机推荐
- Xcode关闭警告
对于关闭某个警告,如果需要全局关闭的话,直接在Other C Flags里写 -Wno-...就行了,比如 -Wextra -Wno-sign-compare 就是一个常见的组合.如果相对某几个文件开 ...
- css table 合并单元格
1. css table 合并单元格 colspan:合并列, rowspan:合并行, 合并行的时候,比如rowspan="2",它的下一行tr会少一列: 合并列的时候,比如co ...
- 2017 清北济南考前刷题Day 5 afternoon
期望得分:100+100+30=230 实际得分:0+0+0=30 T1 直接模拟 #include<cstdio> #include<iostream> using name ...
- 用Python来进行词频统计
# 把语料中的单词全部抽取出来, 转成小写, 并且去除单词中间的特殊符号 def words(text): return re.findall('[a-z]+', text.lower()) def ...
- Java并发编程原理与实战二十七:循环栅栏:CyclicBarrier
昨天我们学习了倒计数功能的等待,今天我们学习的是循环栅栏:CyclicBarrier.下面我们就开始吧: 1.CyclicBarrier简介CyclicBarrier,是JDK1.5的java.uti ...
- idea注册码激活防和谐
1.到网站 http://idea.lanyus.com/ 获取注册码: 2.修改hosts文件,位于C:\Windows\System32\drivers\etc,添加一行,win10推荐使用not ...
- Grep学习笔记
Grep(Global search Regular Expression and Print out the line)是一种强大的文本搜索工具. 1. 正则表达式的基本组成部分 正则表达式 描述 ...
- Xilinx Altera FPGA中的逻辑资源(Slices VS LE)比较
前言 经常有朋友会问我,“我这个方案是用A家的FPGA还是X家的FPGA呢?他们的容量够不够呢?他们的容量怎么比较呢?”当然,在大部分时候,我在给客户做设计的时候,直接会用到最高容量的产品,因为我们的 ...
- CALayer的上动画的暂停和恢复
CHENYILONG Blog CALayer上动画的暂停和恢复 #pragma mark 暂停CALayer的动画-(void)pauseLayer:(CALayer*)layer{CFTimeIn ...
- [CodePlus 2017 11月赛&洛谷P4058]木材 题解(二分答案)
[CodePlus 2017 11月赛&洛谷P4058]木材 Description 有 n棵树,初始时每棵树的高度为 Hi ,第 i棵树每月都会长高 Ai.现在有个木料长度总量为 S的订单, ...