zoukankan      html  css  js  c++  java
  • DOTA版设计模式——迭代器

    迭代器,将遍历集合的方法归一化,不论是ArrayList,普通数组还是其他集合类型,使得遍历集合可以统一管理。
    UML图:

    只要集合都实现了以下接口即可,当然接口函数可以包括Remove等方法,本例列举的是最基础的方法。
        internal interface IIterator
        {
            
    bool HasNext();
            
    object Next();
        }

    也就是说所有的结合类可以判断是否有下一个元素,以及可以返回下一个元素。
    具体的集合类代码如下:
    1.ArrayList:
        internal class ArrayListIterator : IIterator
        {
            
    #region IIterator 成员

            
    public bool HasNext()
            {
                
    if (position > arrayList.Count - 1 || arrayList[position] == null)
                {
                    
    return false;
                }
                
    return true;
            }

            
    public object Next()
            {
                
    object returnValue = arrayList[position];
                position
    ++;
                
    return returnValue;
            }

            
    #endregion

            
    private ArrayList arrayList;
            
    private int position;

            
    public ArrayListIterator(ArrayList arrayList)
            {
                
    this.arrayList = arrayList;
            }
        }

    2.普通数组:
        internal class ArrayIterator : IIterator
        {
            
    #region IIterator 成员

            
    public bool HasNext()
            {
                
    if (position > array.Count - 1 || array[position] == null)
                {
                    
    return false;
                }
                
    return true;
            }

            
    public object Next()
            {
                
    object returnValue = array[position];
                position
    ++;
                
    return returnValue;
            }

            
    #endregion

            
    private IList array;
            
    private int position;

            
    public ArrayIterator(IList array)
            {
                
    this.array = array;
            }
        }
    在framework中已经集成了迭代器,就是我们所说的
    IEnumerator接口和IEnumerable接口。
    使用迭代器类型的集合时需要同一个方法CreateIterator来返回IIterator(相当于IEnumerator接口类型数据,然后可以根据返回的IIterator对象进行统一遍历,当然CreateIterator也可以定义为一个接口(IEnumerable接口)。详细见完整代码。
    下面来说下我们的framework中自带的迭代器,迭代器要继承IEnumerator接口
    class MyI : IEnumerator
        {

            
    private ArrayList al = new ArrayList();
            
    private int index = -1;
            
    public MyI()
            {
                
    for (int i = 0; i < 10; i++)
                {
                    al.Add(i);
                }
            }

            
    #region IEnumerator 成员

            
    public object Current
            {
                
    get { return al[index]; }
            }

            
    public bool MoveNext()
            {
                
    if (index < al.Count - 1)
                {
                    index
    ++;
                    
    return true;
                }
                
    else
                {
                    
    return false;
                }
            }

            
    public void Reset()
            {
                index 
    = -1;
            }

            
    #endregion
        }
    实现了IEnumerator 成员后就完成了我们的迭代器,然后就该完成生成迭代器的类了
    class MyII : IEnumerable
        {
            
    #region IEnumerable 成员

            
    public IEnumerator GetEnumerator()
            {
                
    return new MyI();
            }

            
    #endregion
        }
    当然我们的C#代码可以写的更优雅些,那就需要yield关键字出场了。来看下吧:
    class MyIterator : IEnumerable
        {
            
    private ArrayList al = new ArrayList();
            
    public MyIterator()
            {
                
    for (int i = 0; i < 10; i++)
                {
                    al.Add(i);
                }
            }
            
    #region IEnumerable 成员

            
    public IEnumerator GetEnumerator()
            {
                
    foreach (int tmp in al)
                {
                    
    yield return tmp;
                }
            }

            
    #endregion
        }
    代码yield return tmp;隐藏了迭代器的实现,是不是很简单那?以下是测试代码:
                MyIterator mi = new MyIterator();
                foreach (int tmp in mi)
                {
                    Console.WriteLine(tmp);
                }
                MyII mi2 = new MyII();
                foreach (int tmp in mi2)
                {
                    Console.WriteLine(tmp);
                }
                Console.Read();
    完整代码:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections;

    using DotaCommon;

    namespace DotaPatternLibrary.Iterator
    {
        
    internal interface IIterator
        {
            
    bool HasNext();
            
    object Next();
        }

        
    internal class ArrayListIterator : IIterator
        {
            
    #region IIterator 成员

            
    public bool HasNext()
            {
                
    if (position > arrayList.Count - 1 || arrayList[position] == null)
                {
                    
    return false;
                }
                
    return true;
            }

            
    public object Next()
            {
                
    object returnValue = arrayList[position];
                position
    ++;
                
    return returnValue;
            }

            
    #endregion

            
    private ArrayList arrayList;
            
    private int position;

            
    public ArrayListIterator(ArrayList arrayList)
            {
                
    this.arrayList = arrayList;
            }
        }

        
    internal class ArrayIterator : IIterator
        {
            
    #region IIterator 成员

            
    public bool HasNext()
            {
                
    if (position > array.Count - 1 || array[position] == null)
                {
                    
    return false;
                }
                
    return true;
            }

            
    public object Next()
            {
                
    object returnValue = array[position];
                position
    ++;
                
    return returnValue;
            }

            
    #endregion

            
    private IList array;
            
    private int position;

            
    public ArrayIterator(IList array)
            {
                
    this.array = array;
            }
        }

        
    internal class HeroCollection
        {
            
    private ArrayList heros;
            
    public HeroCollection()
            {
                heros 
    = new ArrayList();
                
    for (int i = 1; i <= 10; i++)
                {
                    Hero hero 
    = new Hero();
                    hero.Name 
    = "ArrayList" + i;
                    heros.Add(hero);
                }
            }

            
    public ArrayList GetHeros()
            {
                
    return heros;
            }

            
    public IIterator CreateIterator()
            {
                
    return new ArrayListIterator(heros);
            }
        }

        
    internal class HeroBackCollection
        {
            
    private Hero[] heros = new Hero[10];
            
    public HeroBackCollection()
            {
                
    for (int i = 0; i < 10; i++)
                {
                    Hero hero 
    = new Hero();
                    hero.Name 
    = "Array" + i;
                    heros[i] 
    = hero;
                }
            }

            
    public Hero[] GetHeros()
            {
                
    return heros;
            }

            
    public IIterator CreateIterator()
            {
                
    return new ArrayIterator(heros);
            }
        }

        
    internal class Hero
        {
            
    private string _name;
            
    public string Name
            {
                
    get { return _name; }
                
    set { _name = value; }
            }
        }

        
    public class Game
        {
            
    public void Start()
            {
                HeroCollection hcObj 
    = new HeroCollection();
                IIterator heros 
    = hcObj.CreateIterator();
                
    while (heros.HasNext())
                {
                    Hero hero 
    = heros.Next() as Hero;
                    LandpyForm.Form.OutputResult(hero.Name);
                }

                HeroBackCollection hbcObj 
    = new HeroBackCollection();
                heros 
    = hbcObj.CreateIterator();
                
    while (heros.HasNext())
                {
                    Hero hero 
    = heros.Next() as Hero;
                    LandpyForm.Form.OutputResult(hero.Name);
                }
            }
        }
    }
  • 相关阅读:
    215. Kth Largest Element in an Array (have better solution )
    414. Third Maximum Number
    442. Find All Duplicates in an Array
    448. Find All Numbers Disappeared in an Array
    485. Max Consecutive Ones
    532. K-diff Pairs in an Array
    8. String to Integer (atoi)
    7. Reverse Integer
    [CTSC2012]熟悉的文章(广义后缀自动机+二分答案+单调队列优化DP)
    BZOJ 2119 股市的预测(后缀数组)
  • 原文地址:https://www.cnblogs.com/pangxiaoliang/p/1531549.html
Copyright © 2011-2022 走看看