精华内容
下载资源
问答
  • 迭代器模式(Iterator Pattern)相信大家都已经见过不少次了,当你学习Java或者其他编程语言的开始你就会接触它,因为集合就是这种设计模式:提供一种方法顺序访问聚合对象中各个元素而又无需暴露该对象的内部表示。...

    一句话概括:

    顺序访问集合对象的元素,不需要知道集合对象的底层表示。

    补充介绍:

    迭代器模式(Iterator Pattern)相信大家都已经见过不少次了,当你学习Java或者其他编程语言的开始你就会接触它,因为集合就是这种设计模式:提供一种方法顺序访问聚合对象中各个元素而又无需暴露该对象的内部表示。

    这种模式将元素之间的游走交给迭代器,而不是具体的聚合对象。从而达到一种低耦合目的。

    关键接口有:hasNext() 判断是否还有下一个元素, next() 下一个元素对象

    参与角色:

    1)聚合类(容器类)接口

    2)具体的容器类

    3)Iterator接口

    4)Iterator实现类

    5)元素类

    优点:

    1、它支持以不同的方式遍历一个聚合对象。 2、迭代器简化了聚合类。 3、在同一个聚合上可以有多个遍历。 4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。

    缺点:

    由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

    使用案例或场景:

    使用场景:需要遍历聚合类

    案例:Java集合框架:List, Set, Map 都支持迭代

     

    示例程序

    需要源码的朋友可以前往github下载:

    https://github.com/aharddreamer/chendong/tree/master/design-patterns/demo-code/design-patterns

    程序简介

    我们将创建一个叙述导航方法的 Iterator 接口和一个返回迭代器的 Container 接口。实现了 Container 接口的实体类将负责实现 Iterator 接口。

     

    IteratorPatternDemo,我们的演示类使用实体类 NamesRepository 来打印 NamesRepository 中存储为集合的 Names。

    代码:

    public interface Iterator {
       public boolean hasNext();
       public Object next();
    }
    
    
    public interface Container {
       public Iterator getIterator();
    }
    
    
    public class NameRepository implements Container {
       public String names[] = {"Robert" , "John" ,"Julie" , "Lora"};
     
       @Override
       public Iterator getIterator() {
          return new NameIterator();
       }
     
       private class NameIterator implements Iterator {
     
          int index;
     
          @Override
          public boolean hasNext() {
             if(index < names.length){
                return true;
             }
             return false;
          }
     
          @Override
          public Object next() {
             if(this.hasNext()){
                return names[index++];
             }
             return null;
          }     
       }
    }
    
    
    
    public class IteratorPatternDemo {
       
       public static void main(String[] args) {
          NameRepository namesRepository = new NameRepository();
     
          for(Iterator iter = namesRepository.getIterator(); iter.hasNext();){
             String name = (String)iter.next();
             System.out.println("Name : " + name);
          }  
       }
    }
    

    输出结果:

    Name : Robert

    Name : John

    Name : Julie

    Name : Lora

     

    参考:

    《迭代器模式》菜鸟教程网站

    展开全文
  • 迭代器与生成器的使用

    千次阅读 2017-12-23 21:56:38
    为什么要有迭代器可迭代的对象迭代器对象迭代器总结迭代器缺点总结生成器什么是生成器生成器就是迭代器yield的功能yield为我们提供了一种自定义迭代器对象的方法yield与return的区别: 1、yield可以返回多次值 ...

    友情提示:查看博客前,请打开目录,查找内容。感谢您前来参考,希望对您有用

    迭代器,迭代的工具

    什么是迭代器?

    指的是一个重复的过程,每一次重复称为一次迭代,并且每一次重复的结果是下一次重复的初始值

    l=['a','b','c']
    count=0
    while count <len(l):
        print(l[count])
        count+=1

    为什么要有迭代器

    1、对于序列类型:str,list,tuple,可以依赖索引来迭代取值
    2、对于dict,set,文件,python必须为我们提供一种不依赖于索引的迭代取值的方式—>迭代器

    可迭代的对象

    对象内置函数带有iter的都称为可迭代的对象

    str     name='lqx'  name.__iter__
    list    l=[1,2,3]   l.__iter__
    tuple   t=(1,2,3)   t.__iter__
    dict    d={'name':'lqx','age':18,'sex':'male'}  d.__iter__
    set     s={'a','b','c'} s.__iter__
    file    f=open('a.txt','w',encoding='utf-8')    f.__iter__

    迭代器对象

    文件即是可迭代对象,也是迭代器对象

    f.__iter__
    f.__next__

    迭代器总结

    1、可迭代对象不一定是迭代器对象
    2、迭代器对象一定是可迭代的对象
    3、调用obj.iter()方式,得到的是迭代器对象(对于迭代器对象,执行iter得打的仍然是它本身)

    d={'name':'egon','age':18,'sex':'male'}
    d_iter=d.__iter__() #使用iter之后,生成的d_iter是迭代器
    print(d_iter,type(d_iter))
    print(d_iter.__next__())  #next的俩种使用方式
    print(next(d_iter))   
    print(next(d_iter))
    print(next(d_iter))  #迭代器d_iter没有值的时候,会抛出异常:StopIteration
    print(next(d_iter))
    如何去除next取不到中导致StopIteration异常
    #下面是如何去除StopIteration异常
    while True:
        try:     #使用try:去除异常
            print(next(d_iter))
        except StopIteration:  #去除异常StopIteration
            break
    for循环详解:

    1、调用in后面的obj_iter=obj.iter()
    2、k=obj_iter.next()
    3、捕捉stopiteration异常,结束迭代

    d={'name':'lqx','age':19,'sex':'male'}
    for k in d:
        print(k)

    迭代器优缺点总结

    优点:
    1、提供一种统一的、不依赖与索引的取值方式,为for循环提供了依据
    2、迭代器同一时间在内存中只有一个值—>更节省内存空间
    缺点:
    1、只能往后取,并且是一次性的
    2、不能统计值的个数,即长度

    l=[1,2,3,4,5]
    l_iter=l.__iter__()
    print(next(l_iter))
    print(next(l_iter))
    print(next(l_iter))
    print(len(l_iter))   #TypeError: object of type 'list_iterator' has no len()

    生成器,就是生成迭代器

    什么是生成器

    只要在函数体内出现yield关键字,那么再执行函数就不会执行函数代码,会得到一个结果,该结果就是生成器

    def func():
        print('---->1')
        yield 1
        print('---->2')
        yield 2
        print('---->3')
        yield 3
    a=func() 
    print(next(a))  #next(a),会执行到第一个yield结束,返回结果是yield后面的返回值
    next(a)
    next(a)
    

    生成器就是迭代器

    g=func()
    res1=next(g)
    print(res1)
    res2=next(g)
    print(res2)
    res3=next(g)
    print(res3)
    >>>
    ---->1
    1
    ---->2
    2
    ---->3
    3

    yield的功能

    yield为我们提供了一种自定义迭代器对象的方法
    yield与return的区别:

    1、yield可以返回多次值
    2、函数暂停与再继续的状态是由yield帮我们保存的
    3、yield在函数中也就是暂停的意思,并且返回yield后面的值

    obj=range(1,1000000000000,2)
    
    obj_iter=obj.__iter__()
    print(next(obj_iter))
    print(next(obj_iter))
    print(next(obj_iter))
    print(next(obj_iter))
    制作一个range内置函数:
    #制作一个range函数
    def range_it(start,stop,step=1):
       while stop > start:
            yield start
            start=start + step
    
    for i in range_it(1,20,2):
        print(i)
    制作一个类似于linux中管道的小程序
    import time
    # 小练习::tail -f access.log | grep '404'
    def tail(filepath): #检测是否有新的写入信息,如果有一条就给yield,作为函数的返回结果。
        with open(filepath,'rb') as f:
            f.seek(0,2)
            while True:
                line=f.readline()
                if line:
                    yield line
                else:
                    time.sleep(0.05)
    
    def grep(lines,pattern): #传入tail检测到新增加的行,然后打印出来这一行并赋值给line,再做判断404,在就使用yield返回这一行
        for line in lines:
            # print(line)
            line=line.decode('utf-8')
            if pattern in line:
                yield line
    
    lines=grep(tail('a.txt'),'404')  #grep()函数执行的结果返回的yield的值,给他赋值,
    for line in lines:        #使用for去循环取出lines中的值
        print(line)
    生成器了解知识点:yield表达式的用法

    生成器使用yield表达式,就是给yield初始化下,然后给他传任意值
    这里需要先给yield传入一个None的值
    e.send:
    1、从暂停的位置将值传给yield
    2、与next一样

    
    def eater(name):
        print('%s ready to eat' %name)
        food_list=[]
        while True:
            food=yield food_list
            food_list.append(food)
            print('%s start to eat %s' %(name,food))
    e=eater('alex')
    #首先要做一个初始化的操作:也就是必须要先给yield传入一个None的值。
    print(e.send(None)) #next(e)  
    print(e.send('一桶水'))  #给yield赋值一次,然后会执行下面的代码,然后循环到下一个yield停止
    print(e.send('一盘骨头'))
    展开全文
  • python中使用迭代器 Iterator

    千次阅读 2015-08-10 15:10:30
    迭代器是访问集合内元素的一...对于原生支持随机访问的数据结构(如tuple、list),迭代器和经典for循环的索引访问相比并无优势,反而丢失了索引值(可以使用内建函数enumerate()找回这个索引值,这是后话)。但对于无

    迭代器是访问集合内元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素都被访问一遍后结束。

    迭代器不能回退,只能往前进行迭代。这并不是什么很大的缺点,因为人们几乎不需要在迭代途中进行回退操作。

    对于原生支持随机访问的数据结构(如tuplelist),迭代器和经典for循环的索引访问相比并无优势,反而丢失了索引值(可以使用内建函数enumerate()找回这个索引值,这是后话)。但对于无法随机访问的数据结构(比如set)而言,迭代器是唯一的访问元素的方式。
    迭代器的另一个优点就是它不要求你事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代至某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件,或是斐波那契数列等等。这个特点被称为延迟计算或惰性求值(Lazy evaluation)。

    迭代器更大的功劳是提供了一个统一的访问集合的接口。只要是实现了iter()方法的对象,就可以使用迭代器进行访问。

    使用迭代器

    使用内建的工厂函数iter(iterable)可以获取迭代器对象:

    > lst = range(3)
    > it = iter(lst)
    > it
    <listiterator object at 0x0251BFD0>
    

    使用迭代器的next()方法可以访问下一个元素:

    it.next()
    0
    next(it)
    1

    两者的效果是一样的。

    Python里的迭代器并没有提供类似has_next()这样的方法,如果迭代器访问到最后一个,再次使用next()函数会引发异常 StopIteration。我们可以通过捕获异常的方式结束。

    >it = iter(lst)
    >try:
        while True:
            val = it.next()
            print val
    >except StopIteration:
        pass

    因为迭代操作如此普遍,Python专门将关键字for用作了迭代器的语法。在for循环中,Python将自动调用工厂函数iter()获得迭代器,自动调用next()获取元素,还完成了检查StopIteration异常的工作。上述代码可以写成如下的形式:

    for val in lst:
        print val

    首先Python将对关键字in后的对象调用iter函数获取迭代器,然后调用迭代器的next方法获取元素,直到抛出StopIteration异常。对迭代器调用iter函数时将返回迭代器自身,所以迭代器也可以用于for语句中,不需要特殊处理。
    常用的几个内建数据结构tuple、list、set、dict都支持迭代器,字符串也可以使用迭代操作。你也可以自己实现一个迭代器,如上所述,只需要在类的iter方法中返回一个对象,这个对象拥有一个next()方法,这个方法能在恰当的时候抛出StopIteration异常即可。

    展开全文
  • 使用Iterator迭代器遍历集合数据

    千次阅读 2018-09-24 16:02:02
    迭代器(Iterator)  迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。  Java中的Iterator...

    迭代器(Iterator)

      迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。

      Java中的Iterator功能比较简单,并且只能单向移动:

      (1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。

      (2) 使用next()获得序列中的下一个元素。

      (3) 使用hasNext()检查序列中是否还有元素。

      (4) 使用remove()将迭代器新返回的元素删除。

      Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。

     

    1、使用迭代器遍历ArrayList集合 

    package com.jredu.oopch07;
     
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
     
    public class Ch05 {
     
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
     
    		List list = new ArrayList<>();
    		
    		//集合
    		list.add(1);
    		list.add(2);
    		list.add(3);
    		
    		//Iterator迭代器
    		//1、获取迭代器
    		Iterator iter = list.iterator();
    		//2、通过循环迭代
    		//hasNext():判断是否存在下一个元素
    		while(iter.hasNext()){
    			//如果存在,则调用next实现迭代
    			//Object-->Integer-->int
    			int j=(int)iter.next();  //把Object型强转成int型
    			System.out.println(j);
    		}
    	}
     
    }
    

    2、使用迭代器遍历Set集合 

    package com.jredu.oopch08;
     
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
     
    public class Ch01 {
     
    	public static void main(String[] args) {
    		//存储数据的地址
    		Set set = new HashSet<>();
    		//存储数据
    		set.add(new Theme(1,"标题1","简介1"));
    		set.add(new Theme(2,"标题2","简介1"));
    		
    		//遍历数据
    		Iterator iter = set.iterator();
    		while(iter.hasNext()){
    			Theme theme = (Theme)iter.next();
    			System.out.println(theme.getId()+theme.getTitle()+theme.getRemark());
    		}
    	}
    }
    

    3、使用迭代器遍历Map集合 

    package com.jredu.oopch08;
     
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
     
    public class Ch03 {
     
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		Map map = new HashMap<>();
    		map.put(1, "a");
    		map.put(2, "b");
    		map.put(3, "c");
    		//所有键值对中的键,组成一个集合
    		Set set = map.keySet();
    		Iterator iter = set.iterator();
    		while(iter.hasNext()){
    			System.out.println(iter.next());//打印出map中的键(1,2,3)
    		}
    		
    		
    		//打印出值
    		//values所有的值组成的一个集合
    		Collection col = map.values();
    		//重写了toString方法
    		System.out.println(col);//打印出a,b,c的值
    	}
     
    }
    
    package com.jredu.oopch08;
     
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
     
    public class Ch04 {
    	
    	public static void main(String[] args) {
    		Map map=new HashMap<>();
    		map.put(1, "a");
    		map.put(2, "b");
    		map.put(3, "c");
    		//必须掌握
    		//所有键值对中的键,组成成一个set集合
    		Set set=map.keySet();
    		System.out.println(set);
    		//values所有的值组成的一个集合
    		Collection col=map.values();
    		System.out.println(col);
    		
    		
    		
    		
    		
    		//获取所有的键和值
    		//entrySet可以得到由所有键值对组成的集合
    		//里边存储的是所有的数据(键-值)
    		Set<Map.Entry<Integer, String>> entrySet=map.entrySet();
    		Iterator<Map.Entry<Integer, String>> iter=entrySet.iterator();
    		while(iter.hasNext()) {
    			Map.Entry<Integer, String> entry=iter.next();
    			System.out.println("键:"+entry.getKey());
    			System.out.println("值:"+entry.getValue());
    		}
    //		Iterator iter=col.iterator();
    //		while(iter.hasNext()) {
    //			System.out.println(iter.next());
    //		}
    //		Iterator iter=set.iterator();
    //		while(iter.hasNext()) {
    //			System.out.println(iter.next());
    //		}
    //		System.out.println(map);
    	}
     
    }
    

     

    foreach循环

    Java 5.0引入了一种新的更加简洁的foreach语法用于数组和容器的遍历,又称增强型的for循环。 它能在不使用下标的情况下遍历集数组或容器,foreach将自动产生每一项元素。

    其基本语法如下:

    for(type element:obj) {     //type:元素类型  elemengt :元素变量  obj:遍历对象,可以为数组或则集合容器

    含有elemengt的语句块  //循环体

    }

    List<String> strList = new ArrayList<>();
    strList.add("111");
    strList.add("222");
    strList.add("333");
     
    for(String str : strList)
     System.out.println(str);
    

    适用范围:对于任何实现Iterable接口的容器都可以使用foreach循环。foreach语法的冒号后面可以有两种类型:一种是数组,另一种是是实现了Iterable接口的类。

    缺点:丢掉了索引信息。 当遍历集合或数组时,如果需要访问集合或数组的下标,那么最好使用旧式的方式来实现循环或遍历,而不要使用增强的for循环,因为它丢失了下标信息。

     

    展开全文
  • 迭代器模式

    2017-08-17 22:10:59
    迭代器模式是应该是java中使用的最多的一种设计模式,迭代器模式如下: 抽象容器:一般是一个接口,提供一个iterator()方法,例如java中的Collection接口,List接口,Set接口等。 具体容器:就是抽象容器的具体实现...
  •  迭代器模式是一种使用频率非常高的设计模式,通过引入迭代器可以将数据的遍历功能从聚合对象中分离出来,聚合对象只负责存储数据,而遍历数据由迭代器来完成。由于很多编程语言的类库都已经实现了迭代器模式,因此...
  • 迭代器

    2016-09-28 09:55:50
    迭代器是一种设计模式,与集合有关。集合也可以看成包含对象的容器,如List、Set、Map、数组。迭代器的作用就是把容器中的对象一个个遍历出来. 用for循环不行吗?为啥要用迭代器方式?这篇文章总结的很好 迭代器...
  • Java中为什么要使用迭代器

    千次阅读 2019-10-27 20:31:47
    一、推出迭代器(iterator)目的 1.从更高的角度进行分析,使用容器有一个缺点:要使用容器,就必须对容器的确切类型编程;如果我们暂且搁置一边,先来说说下面一种情况: (1)如果你在代码中原本对List进行编程,...
  • 迭代器、生成器

    2019-07-04 21:33:00
    # 通过迭代器取值优缺点:​# 优点:不依赖索引,完成取值# 缺点:不能计算长度,不能指定位取值(只能从前往后逐一取值) 可迭代对象 可迭代对象: 有__iter__()方法的对象,调用该方法返回迭代器对象​有哪些:str ...
  • Java迭代器

    2015-08-31 16:08:17
    概念:迭代器(iterator)是一种对象,只要拿到这个对象,使用迭代器就可以遍历这个对象的内部,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。java中常用的迭代方式 1...
  • 迭代器模式学习总结

    2019-05-01 15:37:19
    迭代器模式是一种使用频率非常高的设计模式,用于对一个聚合对象进行遍历。很多语言都定义了迭代器接口。通过引入迭代器可以将数据的遍历功能从聚合对象中分离出来,聚合对象只负责存储数据,而遍历则交给迭代器完成...
  • c++迭代器

    2014-08-16 19:43:15
    1. 迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型。 (1) 每种容器类型都定义了自己的迭代器类型,如vector: ...(2) 使用迭代器读取vector中的每一个元素: vector ivec(10,1); for(vector
  •  如果要问Java中使用最多的一种模式,答案不是单例模式,也不是工厂模式,更不是策略模式,而是迭代器模式,先来看一段代码吧: [java] view plaincopy public static void 
  • C++迭代器使用

    2013-11-14 08:49:28
    1. 迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型。 (1) 每种容器类型都定义了自己的迭代器类型,如vector: ...(2) 使用迭代器读取vector中的每一个元素: vector ivec(10,1); for(vector
  • 迭代器 含有iter和next方法 (包含next方法的可迭代对象就是迭代器) 迭代也叫遍历,作用是节约内存,应用场景:range/xrange,可以使用 isinstance() 判断一个对象是否是 Iterable 对象 可迭代对象 :一个类内部...
  • python 迭代器

    2015-11-21 11:37:23
    3. 迭代器 3.1. 迭代器(Iterator)概述 迭代器是访问集合内元素的一种方式。...迭代器也不是线程安全的,在多线程环境中对可变集合使用迭代器是一个危险的操作。但如果小心谨慎,或者干脆贯彻函数式
  • python迭代器 for循环

    千次阅读 2015-02-11 22:53:55
    3. 迭代器 3.1. 迭代器(Iterator)概述 迭代器是访问集合内元素的一种方式。...迭代器也不是线程安全的,在多线程环境中对可变集合使用迭代器是一个危险的操作。但如果小心谨慎,或者干脆贯彻函数式思想坚持
  • java迭代器模式

    2015-07-12 12:39:35
    迭代器模式又叫做游标模式。 提供一种方法访问一个容器(container)对象中的各个元素,而又不暴露该对象的内容细节。 迭代器模式由以下角色组成: 迭代器角色(Iterator):负责定义访问和遍历元素的接口。 ...
  • 函数迭代器,生成器

    2019-04-04 18:50:02
    迭代器 # 通过迭代器取值优缺点: # 优点:不依赖索引,完成取值 # 缺点:不能计算长度,不能指定位取值...有哪些:str | list | tuple | dict | set | range() | file | 迭代器对象 | enumerate() | 生成器 '''...
  • python-生成器和迭代器

    千次阅读 2019-05-30 14:45:16
    python-生成器和迭代器
  • 在初级研发或测试面试中总会被问到什么是python的迭代器,有什么好处?这个看似很简单的话题说起来似乎感觉自己并不是特别清楚的能讲出来。所以本文记录下自己查阅很多资料后的总结。 【什么是迭代器迭代器是...
  • 迭代器模式 定义:提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节 迭代器模式的结构 抽象迭代器(Iterator)角色:此抽象角色定义出遍历元素所需的接口; 迭代器实现:实现迭代器接口中定义的...
  • 提纲:生成器 ⫋\subsetneqq⫋ 迭代器 ⫋\subsetneqq⫋ 可迭代对象 1. 可迭代对象: 可迭代对象包括: 迭代器 (包括生成器)。 字符串 str,列表 list, 字典 dict,元组 tuple,集合 set。 实现了 __iter__ 方法...
  • 20 迭代器模式

    2015-03-19 20:26:33
    20 迭代器模式 概念:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示 适用场景  一个聚集对象不管是什么都需要遍历的时候  或者对聚集有多种方式遍历时 作用  迭代器...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 42,484
精华内容 16,993
关键字:

使用set迭代器缺点