一.
现在讨论一下,迭代器是怎么设计出来的。
迭代器是取出元素的方式,这个接口有一个方法专门是用来取出元素用的。但是这个方法呢,每个集合中怎么取,它知道吗?它不知道(这个方法也是从众多子类中抽象出来的)。不知道,所以这个迭代器对象是怎么实现的?是依赖于子类实现的。
更具体的说,一个容器,它里面装着东西,那么我们要取里面这些东西,是不是要依赖于这个容器?换一个容器,取得动作就不一样了。为什么?因为每个容器当中,都有自己的数据结构,(就是这个容器里面元素是怎么放的),我得依赖于它的特点来取里面的东西。这就意味着取出的事物,或者取出的对象必须要和容器相关联,迭代器在直接方法容器内部的内容。再说一遍,容器是存储元素用的,最终我们要将元素取出来,取出的是一个对象,那么这个对象,它要做的是要对容器中的元素进行直接访问,那么这个对象就应该是在容器内部完成的实现。迭代器是内部类的设计方式。
每个容器内部都有自己的取出方式,这个取出方式都在容器的内部,这就意味着连这个取出对象的类型都在对象内部,我们外部不知道。为了能建立每个容器内部统一的取出规则,就对其进行了规则的定义,就叫做,里面都做两件事儿,有没有元素(hasNext),取出元素(Next)。怎么判断,怎么取是容器自己实现的,一复制,各个集合里面都是大同小异了。把这些向外一抽象,就抽出来一个共性的类型,这个类型就是专门用于取出元素的类型,就是Iterator,就是迭代器对象,迭代器类型或者接口类型。这些内部的对象都实现接口了。这个接口算什么?这个接口就是这些容器公共的取出方式。有了接口以后,我没有必要去面对这个容器中的每一个取出对象,我只要面对着接口就可以了。我只要找到迭代器接口,我可以用它对每一个容器进行取出动作,。如果不做这个接口,那么每找到一个容器,都要去寻找容器里面的取出动作。现在只要有这个接口,什么容器来了,都能取。因为只要容器实现了取出接口,我们都能用,降低耦合性了。容器和取出方式之间的耦合性降低了。
现在我们来看一下,iterator是不是内部类。到底是不是内部类,看iterator的方法,它怎么来实现的。那么实现方法,它的子类有很多,到底该怎么去找呢?打开一个申明,看到的都是接口中的方法(interface Collection),它里面有一个iterator方法,这个方法需要它的子类去实现的。
哪个子类去实现的?
我们看一下AbstractList,list里面已经实现了iterator这个方法了。返回的是iterator对象。
有对象,这个类new Itr在哪儿呢?里面有private class Itr implements Iterator,就是私有的内部类。它就通过了内部类实现了迭代器。
实现完之后,就定义了自己的一些方法,同时也覆盖了hasNext和next方法,而且这些方法中的内容很多都是这个对象中的方法和内容,它得依赖于这个容器完成这个对象的创建和方法的覆盖。也就是说这些方法用的都是容器中的内容。
因此,迭代器就是一个实现了iterator接口的每一个容器内部的内部对象,但是我们有必要知道它怎么实现的么?是没有必要的,我们只要是获取到了每一个容器的iterator接口,它里面都可以用。我们不需要知道,没必要看这个怎么实现,没必要知道内部类怎么实现的,不需要,它给我返回一个内部类的名字,