ios开发程序员iOS Developer

迭代器模式(Java与iOS)

2016-10-27  本文已影响409人  苏小妖灬

定义:

迭代器模式又叫做游标(Cursor)模式。提供一种方法访问一个容器(container)对象中的各个元素,而又不暴露该对象的内部细节

迭代器模式的结构:

类图:

迭代器模式类图.png

代码示例:

interface Iterator {

    public Object next();

    public boolean hasNext();

}
class ConcreteIterator implements Iterator{

    private List list = new ArrayList();
    private int cursor = 0;

    public ConcreteIterator(List list){

        this.list = list;

    }

    public boolean hasNext() {

        if(cursor==list.size()){

            return false;

        }

        return true;

    }

    public Object next() {

        Object obj = null;

        if(this.hasNext()){

            obj = this.list.get(cursor++);

        }

        return obj;

    }

}
interface Aggregate {

    public void add(Object obj);

    public void remove(Object obj);

    public Iterator iterator();

}
class ConcreteAggregate implements Aggregate {

    private List list = new ArrayList();

    public void add(Object obj) {

        list.add(obj);

    }

    public Iterator iterator() {

        return new ConcreteIterator(list);

    }

    public void remove(Object obj) {

        list.remove(obj);

    }

}
public class Client {

    public static void main(String[] args){

        Aggregate ag = new ConcreteAggregate();
        ag.add("小明");
        ag.add("小红");
        ag.add("小刚");
        Iterator it = ag.iterator();

        while(it.hasNext()){

            String str = (String)it.next();
            System.out.println(str);

        }

    }
}

**深入理解: **

就是把遍历算法从容器对象中独立出来,为什么要把遍历算从容器对象中独立出来呢? 因为在面向对象设计中,一个难点就是辨认对象的职责。理想的状态下,一个类应该只有一个单一的职责。职责分离可以最大限度的去耦合,但是职责单一说起来容易,做起来难。具体到本模式,我们明显可以看到,一个容器对象它提供了两个职责:一是组织管理数据对象,二是提供遍历算法。
  所以:Iterator模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明的访问集合内部的数据。

下面来看看java中部分迭代器的使用:

public interface Iterator<E> {  
  
    boolean hasNext();//判断是否存在下一个对象元素  
  
     E next();  
  
    void remove();  
}
import java.util.*;  
  
public class TestIterator {  
  
  
   public static void main(String[] args) {  
  
          
  
      List list = new ArrayList();  
  
      Map map = new HashMap();  
  
      for(int i = 0;i < 10;i++){  
  
          list.add(new String("list"+i) );  
  
          map.put(i, new String("map"+i));  
  
      }  
  
      Iterator iterList= list.iterator();//List接口实现了Iterable接口  
  
        while(iterList.hasNext()){  
  
          String strList = (String)iterList.next();  
  
          System.out.println(strList.toString());  
  
      }  
  
      Iterator iterMap=map.entrySet().iterator();  
  
      while(iterMap.hasNext()){  
  
          Map.Entry  strMap = (Map.Entry)iterMap.next();  
  
          System.out.println(strMap.getValue());  
  
   
  
      }  
  
   }  
  
}

import java.util.*;  
public class TestIterator {  
  
  
  
   public static void main(String[] args) {  
  
          
  
      List<String>  list=new ArrayList<String> ();  
  
      for(int i=0;i<10;i++){  
  
          list.add(new String("list"+i) );  
  
      }  
  
      for(String str:list){  
  
        System.out.println(str);  
  
      }    
  
}

iOS中迭代器的使用

//1.数组迭代器

    NSArray *array = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil];
        
    // 获取数组的正序迭代器
    NSEnumerator *enu1 = [array objectEnumerator];
        
    // 获取数组的反序迭代器
    NSEnumerator *enu2 = [array reverseObjectEnumerator];
        
    // 遍历数组
    id obj = nil;
        
    // 正序,获取下一个需要遍历的元素
    while (obj = [enu1 nextObject]) {
        NSLog(@"%@", obj);
    }
        
    // 反序,获取下一个需要遍历的元素
    while (obj = [enu2 nextObject]) {
        NSLog(@"%@", obj);
    }
//2.集合迭代器

    NSSet *set = [NSSet setWithObjects:@5, @23, @3, @8, @21, @33, @18, nil];
        
    NSEnumerator *enu = [set objectEnumerator];
        
    id obj = nil;
        
    while (obj = [enu nextObject]) {
        NSLog(@"%@", obj);
    }
//3.字典迭代器

    NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil];
        
    // key 迭代器
    NSEnumerator *keyEnumer = [dic keyEnumerator];
        
    id key = nil;
    while (key = [keyEnumer nextObject]) {
        NSLog(@"%@ = %@", key, [dic objectForKey:key]);
    }
    // 对象迭代器
    NSEnumerator *objEnumer = [dic objectEnumerator];
        
    id obj = nil;
    while (obj = [objEnumer nextObject]) {
        NSLog(@"%@", obj);
    }
//快速遍历
    NSArray *array = @[@"张三", @"李四", @"王五"];
    for (id item in array) {
        NSLog(@"item is :%@", item);
    }
//基于块的枚举

    //数组

    NSArray *array = @[@"张三", @"李四", @"王五"];
    NSString *str = @"李四";
    [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
         NSLog(@"item is :%@", obj);
            
         if ([obj localizedStandardCompare:str] == NSOrderedSame) {
             *stop = YES;
             NSLog(@"停止遍历");
         }
    }];


    //字典
    NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil];
    
    [dic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        
        NSLog(@"item is :%@", obj);
        
    }];


    //set
    NSSet *set = [NSSet setWithObjects:@5, @23, @3, @8, @21, @33, @18, nil];
    
    [set enumerateObjectsUsingBlock:^(id  _Nonnull obj, BOOL * _Nonnull stop) {
        
        NSLog(@"%@", obj);
        
    }];

迭代器模式的优缺点

迭代器模式的适用场景

1. 迭代器模式是与集合共生共死的,一般来说,我们只要实现一个集合,就需要同时提供这个集合的迭代器,就像java中的Collection,List、Set、Map等,这些集合都有自己的迭代器。假如我们要实现一个这样的新的容器,当然也需要引入迭代器模式,给我们的容器实现一个迭代器。
  2. 但是,由于容器与迭代器的关系太密切了,所以大多数语言在实现容器的时候都给提供了迭代器,并且这些语言提供的容器和迭代器在绝大多数情况下就可以满足我们的需要,所以现在需要我们自己去实践迭代器模式的场景还是比较少见的,我们只需要使用语言中已有的容器和迭代器就可以了。

参考书籍

Objective-C编程之道

上一篇下一篇

猜你喜欢

热点阅读