黑马程序员技术交流社区

标题: 对迭代器Iterator的迷惑 [打印本页]

作者: wahaha    时间: 2013-3-8 21:04
标题: 对迭代器Iterator的迷惑
API文档里面对Iterator解释很抠...
无构造函数(或者说private了),很特殊的东西,功能强大..
但就是这么个常用的东西,我们对他真正能有多少了解呢??

深究过的筒子们交流下心得哇...




作者: 李洪因    时间: 2013-3-8 21:14
迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。
  Java中的Iterator功能比较简单,并且只能单向移动:
  (1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。
  (2) 使用next()获得序列中的下一个元素。
  (3) 使用hasNext()检查序列中是否还有元素。
  (4) 使用remove()将迭代器新返回的元素删除。
  Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。
迭代器应用:
list l = new ArrayList();
l.add("aa");
l.add("bb");
l.add("cc");
for (Iterator iter = l.iterator(); iter.hasNext();) {
String str = (String)iter.next();
System.out.println(str);
}
/*迭代器用于while循环
Iterator iter = l.iterator();
while(iter.hasNext()){
String str = (String) iter.next();
System.out.println(str);
}

作者: HM刘博    时间: 2013-3-8 21:20
1.构造函数的命名必须和类名完全相同;在java中普通函数可以和构造函数同名,但是必须带有返回值。
2.构造函数的功能主要用于在类的对象创建时定义初始化的状态。它没有返回值,也不能用void来修饰。这就保证了它不仅什么也不用自动返回,而且根本不能有任何选择。而其他方法都有返回值,即使是void返回值。尽管方法体本身不会自动返回什么,但仍然可以让它返回一些东西,而这些东西可能是不安全的。
3.构造函数不能被直接调用,必须通过new运算符在创建对象时才会自动调用;而一般的方法是在程序执行到它的时候被调用的。
4.当定义一个类的时候,通常情况下都会显示该类的构造函数,并在函数中指定初始化的工作也可省略,不过Java编译器会提供一个默认的构造函数.此默认构造函数是不带参数的。而一般的方法不存在这一特点。
  1. public class UserManagerImpl implements UserManager {
  2. private UserDao userDao;
  3. public UserManagerImpl(UserDao userDao){
  4. this.userDao=userDao;
  5. }
  6. public void save(String username,String password){
  7. this.userDao.save(username, password);
  8. }
  9. }
复制代码
注意: 由于Java不允许像C++那样为函数的参数提供缺省值, 因此在构造函数中也不能使用缺省值.
构造函数的特点:
1.它的函数名与类名相同
2.它可以重载
3.不能指定返回类型,即使是void也不行。
4.它不能被显式调用,在创建对象的时候被自动调用。
作者: 邹学良    时间: 2013-3-8 21:41
本帖最后由 邹学良 于 2013-3-8 21:42 编辑

JAVA中迭代器作为一种模式,它可以使得对于序列类型的数据结构的遍历行为与被遍历的对象分离,即我们无需关心该序列的底层结构是什么样子的。
一般的迭代器对外提供的接口有:
A:检查是否至序列末端。        B:返回当前的对象。        C:过渡到下一个对象。
Iterator模式作为迭代器的简单实现,是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。
例如,如果没有使用Iterator,遍历一个数组的方法是使用索引:
             for(int i=0; i<array.size(); i++) {
                              get(i)。。。;
                     }  
而访问一个链表(LinkedList)又必须使用while循环:
                 while((e=e.next())!=null) {
                                    e.data() 。。。
                  }  
以上两种方法客户端都必须事先知道集合的内部结构,访问代码和集合本身是紧耦合,无法将访问逻辑从集合类和客户端代码中分离出来,每一种集合对应一种遍历方法,客户端代码无法复用。更恐怖的是,如果以后需要把ArrayList更换为LinkedList,则原来的客户端代码必须全部重写。
为解决以上问题,Iterator模式总是用同一种逻辑来遍历集合:
                      for(Iterator it = c.iterater(); it.hasNext(); ) { 。。。 }
奥秘在于客户端自身不维护遍历集合的"指针",所有的内部状态(如当前元素位置,是否有下一个元素)都由Iterator来维护,而这个Iterator由集合类通过工厂方法生成,因此,它知道如何遍历整个集合。客户端从不直接和集合类打交道,它总是控制Iterator,向它发送"向前","向后","取当前元素"的命令,就可以间接遍历整个集合。
首先看看java.util.Iterator接口的定义:了解下它的原理
                               public interface Iterator {
                                          boolean hasNext();
                                          Object next();
                                          void remove();
                                               }
依赖前两个方法就能完成遍历,典型的代码如下:
                             for(Iterator it = c.iterator(); it.hasNext(); ) {
                                                     // 对o的操作。。。                                  
                                   Object o = it.next();            
                                            }
而在JDK1.5中,还对上面的代码在语法上作了简化:如String这个具体的类型
                         for(Type t : c) {}  
每一种集合类返回的Iterator具体类型可能不同,Array可能返回ArrayIterator,Set可能返回SetIterator,Tree可能返回TreeIterator,但是它们都实现了Iterator接口,因此,客户端不关心到底是哪种Iterator,它只需要获得这个Iterator接口即可,而这也就是面向对象的好处所在。
作者: wahaha    时间: 2013-3-8 22:09
求心得...5句话说清楚的,我送金币...copy   DU酿的请绕道...

求心得交流非求扫盲...
作者: 聂斌    时间: 2013-3-9 01:29
迭代器的由来:

每个集合的数据结构不一样,,所以他们存取的方式也会不同,具体实现方法不一样,每个集合都具备取出数据的方式,而这个方式他不足以用一个方法来描述,,不足以就是比如你取的时候取之前要判断下还有没有元素,还有些其他的操作关于取出的,,,对于取出不止一个动作的话,他就把这取出动作封装成对象,,对于取出这个动作不足以用一个方法来描述,他需要用多个功能来体现,,就把这多个功能封装到对象里面去,,这个取出的对象就是迭代器,


特点:
1.迭代器是取出方式,会直接访问集合中的元素。
2迭代器在Collcection接口中是通用的,它替代了Vector类中的Enumeration(枚举)。
3迭代器的next方法是自动向下取元素,要避免出现NoSuchElementException。
4迭代器的next方法返回值类型是Object,所以要记得类型转换。

适用情况:
1. 访问一个容器对象的内容而无需暴露它的内部表示。
2.为遍历不同的容器结构提供一个统一的接口(多态迭代)。


呵呵同学以上就是我个人的理解,

作者: amen0205    时间: 2013-3-9 03:25
额  方法什么的你自己看API  和知道 我说下我的理解吧

1  他是一个内部类    所以可以访问外部类(即集合)的所有成员  这就是他被定义的原因  :在内部方便取出集合的元素
2  不同的集合有不同数据结构  也有不同的排序方式  也有不同的取出方式  所以他的的子类功能繁复  但它很简单那  有下一个就去下一个  顺便还能把不要的丢掉

作者: 谢洋    时间: 2013-3-9 12:58
本帖最后由 谢洋 于 2013-3-9 13:01 编辑

楼上说得没错,再补充一点,这个而且这个内部类是static
我猜:
集合类中封装了一个迭代器类型的 私有成员(如:private static Iterator iterator;
而且内部定义了个与该集合相关的迭代器类(private static class InnerIterator{}),这个类有一些直接操作外部类的方法;
并且有一个方法会生成一个迭代器的对象,并把这人对象赋给集合中定义的私有迭代器成员
(如:this.iterator = new InnerIterator())
最后外部类还定义了一个public static Iterater iterator(){return iterator;}这样一个方法,那么我们就可以取得集合中特定的迭代器了
作者: wahaha    时间: 2013-3-9 15:58
昆哥,...都加分了.为神马就我没加分捏~~~~~伤感..
作者: wahaha    时间: 2013-3-9 15:59
虽然不不是抱着加分的态度来提问的,也学到了东西...可大家都加了滴.....55555
作者: HM周磊    时间: 2013-3-22 11:18
李洪因 发表于 2013-3-8 21:14
迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结 ...

请问:String str = (String) iter.next();这里为什么又要强制转换成字符串类型?





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2