Java源码解析:深化根究Iterator情势[Java编程]
本文“Java源码解析:深化根究Iterator情势[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
java.util包中包含了一系列重要的调集类.本文将从解析源码动手,深化研究一个调集类的内部构造,以及遍历调集的迭代情势的源码实现底细.
下面我们先简单谈论一个根接口Collection,然后解析一个抽象类AbstractList和它的对应Iterator接口,并细心研究迭代子情势的实现原理.
本文谈论的源代码版本是JDK 1.4.2,因为JDK 1.5在java.util中利用了很多泛型代码,为了简化问题,所以我们还是谈论1.4版本的代码.
调集类的根接口Collection
Collection接口是全部调集类的根范例.它的一个主要的接口办法是:
boolean add(Object c)
add()办法将增添一个新元素.注意这个办法会返回一个boolean,但是返回值不是表示增添成功与否.细心阅读doc可以看到,Collection规定:假如一个调集回绝增添这个元素,无论任何缘由,都必须抛出非常.这个返回值表示的意义是add()办法履行后,调集的内容能否改变了(就是元素有没有数目,位置等改变),这是由具体类实现的.即:假如办法出错,总会抛出非常;返回值仅仅表示该办法履行后这个Collection的内容有没有改变.
近似的还有:
boolean addAll(Collection c);
boolean remove(Object o);
boolean removeAll(Collection c);
boolean remainAll(Collection c);
Object[] toArray()办法很简单,把调集转换成数组返回.Object[] toArray(Object[] a)办法就有点复杂了,首先,返回的Object[]仍旧是把调集的全部元素变成的数组,但是范例和参数a的范例是相同的,比方履行:
String[] o = (String[])c.toArray(new String[0]);
得到的o实际范例是String[].
其次,假如参数a的大小装不下调集的全部元素,返回的将是一个新的数组.假如参数a的大小能装下调集的全部元素,则返回的还是a,但a的内容用调集的元从来填充.特别要注意的是,假如a的大小比调集元素的个数还多,a背面的部份全部被置为null.
最后一个最重要的办法是iterator(),返回一个Iterator(迭代子),用于遍历调集的全部元素.
用Iterator情势实现遍历调集
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(); ) {
Object o = it.next();
// 对o的操作...
}
在JDK1.5中,还对上面的代码在语法上作了简化:
// Type是具体的范例,如String.
for(Type t : c) {
// 对t的操作...
}
每一种调集类返回的Iterator具体范例大概差别,Array大概返回ArrayIterator,Set大概返回SetIterator,Tree大概返回TreeIterator,但是它们都实现了Iterator接口,因此,客户端不关心毕竟是哪类Iterator,它只需求得到这个Iterator接口便可,这就是面向对象的威力.
以上是“Java源码解析:深化根究Iterator情势[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |