zoukankan      html  css  js  c++  java
  • 设计模式之美:Iterator(迭代器)

    索引

    意图

    提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。

    Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

    结构

    参与者

    Iterator

    • 迭代器定义访问和遍历元素的接口。

    ConcreteIterator

    • 具体迭代器实现迭代器接口。
    • 对该聚合遍历时跟踪当前位置。

    Aggregate

    • 聚合定义创建相应迭代器对象的接口。

    ConcreteAggregate

    • 具体聚合实现创建相应迭代器的接口,该操作返回 ConreteIterator 的实例。

    适用性

    在以下情况下可以使用 Iterator 模式:

    • 访问一个聚合对象的内容而无需暴露它的内部表示。
    • 支持对聚合对象的多种遍历。
    • 为遍历不同的聚合结构提供一个统一的接口。

    效果

    • 它支持以不同的方式遍历一个聚合。
    • 迭代器简化了聚合的接口。
    • 在同一个聚合上可以有多个遍历。

    相关模式

    • Iterator 常被应用到 Composite 这样的递归结构上。
    • 可以使用 Factory Method 模式来实例化多态迭代器。
    • Iterator 可以使用 Memento 来捕获一个迭代的状态,在内部存储 Memento。

    实现

    实现方式(一):Iterator 模式结构样式代码。

      1 namespace IteratorPattern.Implementation1
      2 {
      3   public abstract class Iterator
      4   {
      5     public abstract object First();
      6     public abstract object MoveNext();
      7     public abstract object Current();
      8     public abstract bool IsDone();
      9     public abstract void Reset();
     10   }
     11 
     12   public abstract class Aggregate
     13   {
     14     public abstract Iterator CreateIterator();
     15   }
     16 
     17   public class ConcreteAggregate : Aggregate
     18   {
     19     private readonly ArrayList _items = new ArrayList();
     20 
     21     public int Count
     22     {
     23       get { return _items.Count; }
     24     }
     25 
     26     public object this[int index]
     27     {
     28       get { return _items[index]; }
     29       set { _items.Insert(index, value); }
     30     }
     31 
     32     public override Iterator CreateIterator()
     33     {
     34       return new ConcreteIterator(this);
     35     }
     36   }
     37 
     38   public class ConcreteIterator : Iterator
     39   {
     40     private readonly ConcreteAggregate _aggregate;
     41     private int _currentIndex = 0;
     42 
     43     public ConcreteIterator(ConcreteAggregate aggregate)
     44     {
     45       _aggregate = aggregate;
     46     }
     47 
     48     public override object First()
     49     {
     50       if (_aggregate.Count > 0)
     51         return _aggregate[0];
     52       else
     53         return null;
     54     }
     55 
     56     public override object MoveNext()
     57     {
     58       object item = null;
     59       if (_currentIndex < _aggregate.Count - 1)
     60       {
     61         item = _aggregate[++_currentIndex];
     62       }
     63 
     64       return item;
     65     }
     66 
     67     public override object Current()
     68     {
     69       return _aggregate[_currentIndex];
     70     }
     71 
     72     public override bool IsDone()
     73     {
     74       return _currentIndex >= _aggregate.Count;
     75     }
     76 
     77     public override void Reset()
     78     {
     79       _currentIndex = 0;
     80     }
     81   }
     82 
     83   public class Client
     84   {
     85     public void TestCase1()
     86     {
     87       var aggregate = new ConcreteAggregate();
     88       aggregate[0] = "Apple";
     89       aggregate[1] = "Orange";
     90       aggregate[2] = "Strawberry";
     91 
     92       var iterator = new ConcreteIterator(aggregate);
     93 
     94       object item = iterator.First();
     95       while (!iterator.IsDone())
     96       {
     97         Console.WriteLine(item);
     98         item = iterator.MoveNext();
     99       }
    100     }
    101   }
    102 }

    实现方式(二):实现 IEnumerable 中序遍历二叉树。

      1   /// <summary>
      2   /// 二叉树节点
      3   /// </summary>
      4   /// <typeparam name="T">The item type</typeparam>
      5   public class BinaryTreeNode<T>
      6   {
      7     #region Constructors
      8 
      9     /// <summary>
     10     /// 二叉树节点
     11     /// </summary>
     12     public BinaryTreeNode()
     13     {
     14     }
     15 
     16     /// <summary>
     17     /// 二叉树节点
     18     /// </summary>
     19     /// <param name="value">节点中的值</param>
     20     public BinaryTreeNode(T value)
     21     {
     22       this.Value = value;
     23     }
     24 
     25     /// <summary>
     26     /// 二叉树节点
     27     /// </summary>
     28     /// <param name="value">节点中的值</param>
     29     /// <param name="parent">节点的父节点</param>
     30     public BinaryTreeNode(T value, BinaryTreeNode<T> parent)
     31     {
     32       this.Value = value;
     33       this.Parent = parent;
     34     }
     35 
     36     /// <summary>
     37     /// 二叉树节点
     38     /// </summary>
     39     /// <param name="value">节点中的值</param>
     40     /// <param name="parent">节点的父节点</param>
     41     /// <param name="left">节点的左节点</param>
     42     /// <param name="right">节点的右节点</param>
     43     public BinaryTreeNode(T value, 
     44       BinaryTreeNode<T> parent, 
     45       BinaryTreeNode<T> left, 
     46       BinaryTreeNode<T> right)
     47     {
     48       this.Value = value;
     49       this.Right = right;
     50       this.Left = left;
     51       this.Parent = parent;
     52     }
     53 
     54     #endregion
     55 
     56     #region Properties
     57 
     58     /// <summary>
     59     /// 节点值
     60     /// </summary>
     61     public T Value { get; set; }
     62 
     63     /// <summary>
     64     /// 父节点
     65     /// </summary>
     66     public BinaryTreeNode<T> Parent { get; set; }
     67 
     68     /// <summary>
     69     /// 左节点
     70     /// </summary>
     71     public BinaryTreeNode<T> Left { get; set; }
     72 
     73     /// <summary>
     74     /// 右节点
     75     /// </summary>
     76     public BinaryTreeNode<T> Right { get; set; }
     77 
     78     /// <summary>
     79     /// 是否为根节点
     80     /// </summary>
     81     public bool IsRoot { get { return Parent == null; } }
     82 
     83     /// <summary>
     84     /// 是否为叶子节点
     85     /// </summary>
     86     public bool IsLeaf { get { return Left == null && Right == null; } }
     87 
     88     /// <summary>
     89     /// 是否为可访问的
     90     /// </summary>
     91     internal bool Visited { get; set; }
     92 
     93     #endregion
     94 
     95     #region Public Overridden Functions
     96 
     97     /// <summary>
     98     /// Returns a <see cref="System.String"/> that represents this instance.
     99     /// </summary>
    100     /// <returns>
    101     /// A <see cref="System.String"/> that represents this instance.
    102     /// </returns>
    103     public override string ToString()
    104     {
    105       return Value.ToString();
    106     }
    107 
    108     #endregion
    109   }
      1   /// <summary>
      2   /// 二叉树
      3   /// </summary>
      4   /// <typeparam name="T">二叉树中节点内容类型</typeparam>
      5   [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
      6   public class BinaryTree<T> : ICollection<T>, IEnumerable<T> where T : IComparable<T>
      7   {
      8     #region Constructor
      9 
     10     /// <summary>
     11     /// 二叉树
     12     /// </summary>
     13     public BinaryTree()
     14     {
     15       NumberOfNodes = 0;
     16     }
     17 
     18     /// <summary>
     19     /// 二叉树
     20     /// </summary>
     21     /// <param name="root">二叉树根节点</param>
     22     public BinaryTree(BinaryTreeNode<T> root)
     23       : this()
     24     {
     25       this.Root = root;
     26     }
     27 
     28     #endregion
     29 
     30     #region Properties
     31 
     32     /// <summary>
     33     /// 树的根节点
     34     /// </summary>
     35     public BinaryTreeNode<T> Root { get; set; }
     36 
     37     /// <summary>
     38     /// 树中节点的数量
     39     /// </summary>
     40     protected int NumberOfNodes { get; set; }
     41 
     42     /// <summary>
     43     /// 树是否为空
     44     /// </summary>
     45     public bool IsEmpty { get { return Root == null; } }
     46 
     47     /// <summary>
     48     /// 获取树中节点的最小值
     49     /// </summary>
     50     public T MinValue
     51     {
     52       get
     53       {
     54         if (IsEmpty)
     55           return default(T);
     56 
     57         BinaryTreeNode<T> minNode = Root;
     58         while (minNode.Left != null)
     59           minNode = minNode.Left;
     60 
     61         return minNode.Value;
     62       }
     63     }
     64 
     65     /// <summary>
     66     /// 获取树中节点的最大值
     67     /// </summary>
     68     public T MaxValue
     69     {
     70       get
     71       {
     72         if (IsEmpty)
     73           return default(T);
     74 
     75         BinaryTreeNode<T> maxNode = Root;
     76         while (maxNode.Right != null)
     77           maxNode = maxNode.Right;
     78 
     79         return maxNode.Value;
     80       }
     81     }
     82 
     83     #endregion
     84 
     85     #region IEnumerable<T> Members
     86 
     87     /// <summary>
     88     /// Returns an enumerator that iterates through the collection.
     89     /// </summary>
     90     /// <returns>
     91     /// A <see cref="T:System.Collections.Generic.IEnumerator`1"></see> 
     92     /// that can be used to iterate through the collection.
     93     /// </returns>
     94     public IEnumerator<T> GetEnumerator()
     95     {
     96       foreach (BinaryTreeNode<T> node in Traverse(Root))
     97       {
     98         yield return node.Value;
     99       }
    100     }
    101 
    102     #endregion
    103 
    104     #region IEnumerable Members
    105 
    106     /// <summary>
    107     /// Returns an enumerator that iterates through a collection.
    108     /// </summary>
    109     /// <returns>
    110     /// An <see cref="T:System.Collections.IEnumerator"/> 
    111     /// object that can be used to iterate through the collection.
    112     /// </returns>
    113     IEnumerator IEnumerable.GetEnumerator()
    114     {
    115       foreach (BinaryTreeNode<T> node in Traverse(Root))
    116       {
    117         yield return node.Value;
    118       }
    119     }
    120 
    121     #endregion
    122 
    123     #region ICollection<T> Members
    124 
    125     /// <summary>
    126     /// 新增节点
    127     /// </summary>
    128     /// <param name="item">The object to add to the 
    129     /// <see cref="T:System.Collections.Generic.ICollection`1"></see>.</param>
    130     /// <exception cref="T:System.NotSupportedException">The 
    131     /// <see cref="T:System.Collections.Generic.ICollection`1"></see> 
    132     /// is read-only.</exception>
    133     public void Add(T item)
    134     {
    135       if (Root == null)
    136       {
    137         Root = new BinaryTreeNode<T>(item);
    138         ++NumberOfNodes;
    139       }
    140       else
    141       {
    142         Insert(item);
    143       }
    144     }
    145 
    146     /// <summary>
    147     /// 清除树
    148     /// </summary>
    149     public void Clear()
    150     {
    151       Root = null;
    152     }
    153 
    154     /// <summary>
    155     /// 树中是否包含此节点
    156     /// </summary>
    157     /// <param name="item">The object to locate in the 
    158     /// <see cref="T:System.Collections.Generic.ICollection`1"></see>.</param>
    159     /// <returns>
    160     /// true if item is found in the 
    161     /// <see cref="T:System.Collections.Generic.ICollection`1"></see>; otherwise, false.
    162     /// </returns>
    163     public bool Contains(T item)
    164     {
    165       if (IsEmpty)
    166         return false;
    167 
    168       BinaryTreeNode<T> currentNode = Root;
    169       while (currentNode != null)
    170       {
    171         int comparedValue = currentNode.Value.CompareTo(item);
    172         if (comparedValue == 0)
    173           return true;
    174         else if (comparedValue < 0)
    175           currentNode = currentNode.Left;
    176         else
    177           currentNode = currentNode.Right;
    178       }
    179 
    180       return false;
    181     }
    182 
    183     /// <summary>
    184     /// 将树中节点拷贝至目标数组
    185     /// </summary>
    186     /// <param name="array">The array.</param>
    187     /// <param name="arrayIndex">Index of the array.</param>
    188     public void CopyTo(T[] array, int arrayIndex)
    189     {
    190       T[] tempArray = new T[NumberOfNodes];
    191       int counter = 0;
    192       foreach (T value in this)
    193       {
    194         tempArray[counter] = value;
    195         ++counter;
    196       }
    197       Array.Copy(tempArray, 0, array, arrayIndex, Count);
    198     }
    199 
    200     /// <summary>
    201     /// 树中节点的数量
    202     /// </summary>
    203     public int Count
    204     {
    205       get { return NumberOfNodes; }
    206     }
    207 
    208     /// <summary>
    209     /// 树是否为只读
    210     /// </summary>
    211     public bool IsReadOnly
    212     {
    213       get { return false; }
    214     }
    215 
    216     /// <summary>
    217     /// 移除节点
    218     /// </summary>
    219     /// <param name="item">节点值</param>
    220     /// <returns>是否移除成功</returns>
    221     public bool Remove(T item)
    222     {
    223       BinaryTreeNode<T> node = Find(item);
    224       if (node == null)
    225         return false;
    226 
    227       List<T> values = new List<T>();
    228       foreach (BinaryTreeNode<T> l in Traverse(node.Left))
    229       {
    230         values.Add(l.Value);
    231       }
    232       foreach (BinaryTreeNode<T> r in Traverse(node.Right))
    233       {
    234         values.Add(r.Value);
    235       }
    236 
    237       if (node.Parent.Left == node)
    238       {
    239         node.Parent.Left = null;
    240       }
    241       else
    242       {
    243         node.Parent.Right = null;
    244       }
    245 
    246       node.Parent = null;
    247 
    248       foreach (T v in values)
    249       {
    250         this.Add(v);
    251       }
    252 
    253       return true;
    254     }
    255 
    256     #endregion
    257 
    258     #region Private Functions
    259 
    260     /// <summary>
    261     /// 查找指定值的节点
    262     /// </summary>
    263     /// <param name="value">指定值</param>
    264     /// <returns>
    265     /// 指定值的节点
    266     /// </returns>
    267     protected BinaryTreeNode<T> Find(T value)
    268     {
    269       foreach (BinaryTreeNode<T> node in Traverse(Root))
    270         if (node.Value.Equals(value))
    271           return node;
    272       return null;
    273     }
    274 
    275     /// <summary>
    276     /// 遍历树
    277     /// </summary>
    278     /// <param name="node">遍历搜索的起始节点</param>
    279     /// <returns>
    280     /// The individual items from the tree
    281     /// </returns>
    282     [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
    283     protected IEnumerable<BinaryTreeNode<T>> Traverse(BinaryTreeNode<T> node)
    284     {
    285       // 遍历左子树
    286       if (node.Left != null)
    287       {
    288         foreach (BinaryTreeNode<T> left in Traverse(node.Left))
    289           yield return left;
    290       }
    291 
    292       // 中序遍历二叉树, 顺序是 左子树,根,右子树
    293       yield return node;
    294 
    295       // 遍历右子树
    296       if (node.Right != null)
    297       {
    298         foreach (BinaryTreeNode<T> right in Traverse(node.Right))
    299           yield return right;
    300       }
    301     }
    302 
    303     /// <summary>
    304     /// 插入节点
    305     /// </summary>
    306     /// <param name="value">插入的节点值</param>
    307     protected void Insert(T value)
    308     {
    309       // 从根节点开始比较
    310       BinaryTreeNode<T> currentNode = Root;
    311       
    312       while (true)
    313       {
    314         if (currentNode == null)
    315           throw new InvalidProgramException("The current tree node cannot be null.");
    316 
    317         // 比较当前节点与新节点的值
    318         int comparedValue = currentNode.Value.CompareTo(value);
    319         if (comparedValue < 0)
    320         {
    321           // 当前节点值小于新节点值
    322           if (currentNode.Left == null)
    323           {
    324             currentNode.Left = new BinaryTreeNode<T>(value, currentNode);
    325             ++NumberOfNodes;
    326             return;
    327           }
    328           else
    329           {
    330             currentNode = currentNode.Left;
    331           }
    332         }
    333         else if (comparedValue > 0)
    334         {
    335           // 当前节点值大于新节点值
    336           if (currentNode.Right == null)
    337           {
    338             currentNode.Right = new BinaryTreeNode<T>(value, currentNode);
    339             ++NumberOfNodes;
    340             return;
    341           }
    342           else
    343           {
    344             currentNode = currentNode.Right;
    345           }
    346         }
    347         else
    348         {
    349           // 当前节点值等于新节点值
    350           currentNode = currentNode.Right;
    351         }
    352       }
    353     }
    354 
    355     #endregion
    356   }

    实现方式(三):实现 BidirectionalConcurrentDictionary 双向并发字典。

      1 namespace IteratorPattern.Implementation3
      2 {
      3   /// <summary>
      4   /// 双值对
      5   /// </summary>
      6   /// <typeparam name="TFirst">第一个值的类型</typeparam>
      7   /// <typeparam name="TSecond">第二个值的类型</typeparam>
      8   [Serializable]
      9   public struct FirstSecondPair<TFirst, TSecond>
     10   {
     11     private TFirst first;
     12     private TSecond second;
     13 
     14     /// <summary>
     15     /// 第一个值
     16     /// </summary>
     17     public TFirst First
     18     {
     19       get
     20       {
     21         return this.first;
     22       }
     23     }
     24 
     25     /// <summary>
     26     /// 第二个值
     27     /// </summary>
     28     public TSecond Second
     29     {
     30       get
     31       {
     32         return this.second;
     33       }
     34     }
     35 
     36     /// <summary>
     37     /// 双值对
     38     /// </summary>
     39     /// <param name="first">第一个值</param>
     40     /// <param name="second">第二个值</param>
     41     public FirstSecondPair(TFirst first, TSecond second)
     42     {
     43       if (first == null)
     44         throw new ArgumentNullException("first");
     45       if (second == null)
     46         throw new ArgumentNullException("second");
     47 
     48       this.first = first;
     49       this.second = second;
     50     }
     51 
     52     /// <summary>
     53     /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
     54     /// </summary>
     55     /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
     56     /// <returns>
     57     ///   <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
     58     /// </returns>
     59     public override bool Equals(object obj)
     60     {
     61       if (obj == null)
     62         return false;
     63 
     64       FirstSecondPair<TFirst, TSecond> target = (FirstSecondPair<TFirst, TSecond>)obj;
     65       return this.First.Equals(target.First) && this.Second.Equals(target.Second);
     66     }
     67 
     68     /// <summary>
     69     /// Returns a hash code for this instance.
     70     /// </summary>
     71     /// <returns>
     72     /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
     73     /// </returns>
     74     public override int GetHashCode()
     75     {
     76       return base.GetHashCode();
     77     }
     78 
     79     /// <summary>
     80     /// Returns a <see cref="System.String"/> that represents this instance.
     81     /// </summary>
     82     /// <returns>
     83     /// A <see cref="System.String"/> that represents this instance.
     84     /// </returns>
     85     public override string ToString()
     86     {
     87       StringBuilder sb = new StringBuilder();
     88       sb.Append('[');
     89 
     90       if (this.First != null)
     91       {
     92         sb.Append(this.First.ToString());
     93       }
     94 
     95       sb.Append(", ");
     96 
     97       if (this.Second != null)
     98       {
     99         sb.Append(this.Second.ToString());
    100       }
    101 
    102       sb.Append(']');
    103 
    104       return sb.ToString();
    105     }
    106 
    107     /// <summary>
    108     /// Implements the operator ==.
    109     /// </summary>
    110     /// <param name="left">The left.</param>
    111     /// <param name="right">The right.</param>
    112     /// <returns>
    113     /// The result of the operator.
    114     /// </returns>
    115     public static bool operator ==(FirstSecondPair<TFirst, TSecond> left, FirstSecondPair<TFirst, TSecond> right)
    116     {
    117       if (((object)left == null) || ((object)right == null))
    118       {
    119         return false;
    120       }
    121 
    122       return left.Equals(right);
    123     }
    124 
    125     /// <summary>
    126     /// Implements the operator !=.
    127     /// </summary>
    128     /// <param name="left">The left.</param>
    129     /// <param name="right">The right.</param>
    130     /// <returns>
    131     /// The result of the operator.
    132     /// </returns>
    133     public static bool operator !=(FirstSecondPair<TFirst, TSecond> left, FirstSecondPair<TFirst, TSecond> right)
    134     {
    135       return !(left == right);
    136     }
    137   }
    138 
    139   public class BidirectionalConcurrentDictionary<TFirst, TSecond> : IEnumerable<FirstSecondPair<TFirst, TSecond>>
    140   {
    141     #region Fields
    142 
    143     private ConcurrentDictionary<TFirst, TSecond> firstToSecond = new ConcurrentDictionary<TFirst, TSecond>();
    144     private ConcurrentDictionary<TSecond, TFirst> secondToFirst = new ConcurrentDictionary<TSecond, TFirst>();
    145 
    146     #endregion
    147 
    148     #region Public Methods
    149 
    150     public void Add(TFirst first, TSecond second)
    151     {
    152       if (firstToSecond.ContainsKey(first) || secondToFirst.ContainsKey(second))
    153         throw new ArgumentException("Duplicate first or second");
    154 
    155       firstToSecond.Add(first, second);
    156       secondToFirst.Add(second, first);
    157     }
    158 
    159     public bool ContainsFirst(TFirst first)
    160     {
    161       return firstToSecond.ContainsKey(first);
    162     }
    163 
    164     public bool ContainsSecond(TSecond second)
    165     {
    166       return secondToFirst.ContainsKey(second);
    167     }
    168 
    169     public TSecond GetByFirst(TFirst first)
    170     {
    171       TSecond second;
    172       if (!firstToSecond.TryGetValue(first, out second))
    173         throw new KeyNotFoundException("Cannot find second by first.");
    174 
    175       return second;
    176     }
    177 
    178     public TFirst GetBySecond(TSecond second)
    179     {
    180       TFirst first;
    181       if (!secondToFirst.TryGetValue(second, out first))
    182         throw new KeyNotFoundException("Cannot find first by second.");
    183 
    184       return first;
    185     }
    186 
    187     public void RemoveByFirst(TFirst first)
    188     {
    189       TSecond second;
    190       if (!firstToSecond.TryGetValue(first, out second))
    191         throw new KeyNotFoundException("Cannot find second by first.");
    192 
    193       firstToSecond.Remove(first);
    194       secondToFirst.Remove(second);
    195     }
    196 
    197     public void RemoveBySecond(TSecond second)
    198     {
    199       TFirst first;
    200       if (!secondToFirst.TryGetValue(second, out first))
    201         throw new KeyNotFoundException("Cannot find first by second.");
    202 
    203       secondToFirst.Remove(second);
    204       firstToSecond.Remove(first);
    205     }
    206 
    207     public bool TryAdd(TFirst first, TSecond second)
    208     {
    209       if (firstToSecond.ContainsKey(first) || secondToFirst.ContainsKey(second))
    210         return false;
    211 
    212       firstToSecond.Add(first, second);
    213       secondToFirst.Add(second, first);
    214       return true;
    215     }
    216 
    217     public bool TryGetByFirst(TFirst first, out TSecond second)
    218     {
    219       return firstToSecond.TryGetValue(first, out second);
    220     }
    221 
    222     public bool TryGetBySecond(TSecond second, out TFirst first)
    223     {
    224       return secondToFirst.TryGetValue(second, out first);
    225     }
    226 
    227     public bool TryRemoveByFirst(TFirst first)
    228     {
    229       TSecond second;
    230       if (!firstToSecond.TryGetValue(first, out second))
    231         return false;
    232 
    233       firstToSecond.Remove(first);
    234       secondToFirst.Remove(second);
    235       return true;
    236     }
    237 
    238     public bool TryRemoveBySecond(TSecond second)
    239     {
    240       TFirst first;
    241       if (!secondToFirst.TryGetValue(second, out first))
    242         return false;
    243 
    244       secondToFirst.Remove(second);
    245       firstToSecond.Remove(first);
    246       return true;
    247     }
    248 
    249     public int Count
    250     {
    251       get { return firstToSecond.Count; }
    252     }
    253 
    254     public void Clear()
    255     {
    256       firstToSecond.Clear();
    257       secondToFirst.Clear();
    258     }
    259 
    260     #endregion
    261 
    262     #region IEnumerable<FirstSecondPair<TFirst,TSecond>> Members
    263 
    264     IEnumerator<FirstSecondPair<TFirst, TSecond>> IEnumerable<FirstSecondPair<TFirst, TSecond>>.GetEnumerator()
    265     {
    266       foreach (var item in firstToSecond)
    267       {
    268         yield return new FirstSecondPair<TFirst, TSecond>(item.Key, item.Value);
    269       }
    270     }
    271 
    272     #endregion
    273 
    274     #region IEnumerable Members
    275 
    276     IEnumerator IEnumerable.GetEnumerator()
    277     {
    278       foreach (var item in firstToSecond)
    279       {
    280         yield return new FirstSecondPair<TFirst, TSecond>(item.Key, item.Value);
    281       }
    282     }
    283 
    284     #endregion
    285   }
    286 
    287   public static class ConcurrentDictionaryExtensions
    288   {
    289     public static TValue Add<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> collection, TKey key, TValue @value)
    290     {
    291       TValue result = collection.AddOrUpdate(key, @value, (k, v) => { return @value; });
    292       return result;
    293     }
    294 
    295     public static TValue Update<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> collection, TKey key, TValue @value)
    296     {
    297       TValue result = collection.AddOrUpdate(key, @value, (k, v) => { return @value; });
    298       return result;
    299     }
    300 
    301     public static TValue Get<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> collection, TKey key)
    302     {
    303       TValue @value = default(TValue);
    304       collection.TryGetValue(key, out @value);
    305       return @value;
    306     }
    307 
    308     public static TValue Remove<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> collection, TKey key)
    309     {
    310       TValue @value = default(TValue);
    311       collection.TryRemove(key, out @value);
    312       return @value;
    313     }
    314   }
    315 }

    实现方式(四):实现 RoundRobin 循环列表。

     1 namespace IteratorPattern.Implementation4
     2 {
     3   /// <summary>
     4   /// 循环列表
     5   /// </summary>
     6   /// <typeparam name="T"></typeparam>
     7   public class RoundRobinCollection<T> : IEnumerable<T>
     8   {
     9     private T[] _items;
    10     private int _head;
    11 
    12     /// <summary>
    13     /// 循环列表
    14     /// </summary>
    15     /// <param name="items">供循环的列表项</param>
    16     public RoundRobinCollection(IEnumerable<T> items)
    17     {
    18       if (items == null || items.Count<T>() == 0)
    19       {
    20         throw new ArgumentException(
    21           "One or more items must be provided", "items");
    22       }
    23 
    24       // copy the list to ensure it doesn't change on us 
    25       // (and so we can lock() on our private copy) 
    26       _items = items.ToArray();
    27     }
    28 
    29     /// <summary>
    30     /// 获取循环器
    31     /// </summary>
    32     /// <returns></returns>
    33     public IEnumerator<T> GetEnumerator()
    34     {
    35       int currentHead;
    36 
    37       lock (_items)
    38       {
    39         currentHead = _head++;
    40 
    41         if (_head == _items.Length)
    42         {
    43           // wrap back to the start 
    44           _head = 0;
    45         }
    46       }
    47 
    48       // return results [current] ... [last] 
    49       for (int i = currentHead; i < _items.Length; i++)
    50       {
    51         yield return _items[i];
    52       }
    53 
    54       // return wrap-around (if any) [0] ... [current-1] 
    55       for (int i = 0; i < currentHead; i++)
    56       {
    57         yield return _items[i];
    58       }
    59     }
    60 
    61     /// <summary>
    62     /// 获取循环器
    63     /// </summary>
    64     /// <returns></returns>
    65     IEnumerator IEnumerable.GetEnumerator()
    66     {
    67       return this.GetEnumerator();
    68     }
    69   }
    70 }

    设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。

  • 相关阅读:
    不可小视视图对效率的影响力
    Maximum Margin Planning
    PhysicsBased Boiling Simulation

    Learning Behavior Styles with Inverse Reinforcement Learning
    Simulating Biped Behaviors from Human Motion Data
    Nearoptimal Character Animation with Continuous Control
    Apprenticeship Learning via Inverse Reinforcement Learning
    回报函数学习的学徒学习综述
    Enabling Realtime Physics Simulation in Future Interactive Entertainment
  • 原文地址:https://www.cnblogs.com/gaochundong/p/design_pattern_iterator.html
Copyright © 2011-2022 走看看