您的位置:首页 > 编程语言 > Java开发

java容器系列 —— 从Iterator说起

2016-04-18 11:40 405 查看
工作了一段时间,越发觉得基础的东西很重要,尤其是想要提升自生代码质量的时候。所以在工作之余,又开始看《JAVA编程思想》这本书,感觉收获颇丰,尤其是在看java容量类相关章节时,还参照了相关源码。为了与大家共享,同时加深自身理解,打算写成一个系列,有任何错误纰漏之处望指正。

想了很久,打算从Iterator说起。想必大家在开发过程中都使用过Iterator来遍历容器类,其实Iterator只是一个基于泛型的接口:

public interface Iterator<E> {
public boolean hasNext();
public E next();
public void remove();
}


接口就只有上述几个方法,可以很容易从字面意思看出相应方法的含义。而在每个容器类中都定义了内部类来实现该接口,并通过Iterator()方法来返回对应内部类的一个对象实例,从而使我们可以调用接口中的方法来完成遍历。比如在抽象类AbstractList中有一个SimpleListIterator内部类:

private class SimpleListIterator implements Iterator<E> {
int pos = -1;

int expectedModCount;

int lastPosition = -1;

SimpleListIterator() {
expectedModCount = modCount;
}

public boolean hasNext() {
return pos + 1 < size();
}

public E next() {
if (expectedModCount == modCount) {
try {
E result = get(pos + 1);
lastPosition = ++pos;
return result;
} catch (IndexOutOfBoundsException e) {
throw new NoSuchElementException();
}
}
throw new ConcurrentModificationException();
}

public void remove() {
if (this.lastPosition == -1) {
throw new IllegalStateException();
}

if (expectedModCount != modCount) {
throw new ConcurrentModificationException();
}

try {
AbstractList.this.remove(lastPosition);
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}

expectedModCount = modCount;
if (pos == lastPosition) {
pos--;
}
lastPosition = -1;
}
}


在上述代码中,size(),get,remove等方法都是list接口中的方法。需要说明的一点就是expectedModCount这个参数,从上述代码里可以看出这个参数是在对象构造方法中赋值的,赋的值为modCount,在完成赋值操作后,expectedModCount在对象生命周期内就不会更改,只是在get和remove时将expectedModCount与modCount进行对比,如果两者不相等,则抛出ConcurrentModificationException异常,这个异常在线程不安全的容器类中很常见。而导致这个异常的原因正是在用Iterator变量容器类时,另外线程对容器类进行了结构性的修改,导致modCount发生变化。

通过上述代码可以看出,实现一个Iterator接口很简单。而Iterator作为一个接口,我们也可以在自定义的类中实现该接口,从而使其方法可以通过Iterator遍历我们自身类中的数据集。比如:

public class CrossContainerIteration {
public static void display(Iterator<Pet> it) {
while(it.hasNext()) {
Pet p = it.next();
}
}
public static void main(String[] args) {
ArrayList<Pet> pets = Pets.arrayList(8);
LinkedList<Pet> petsLL = new LinkedList<Pet>(pets);
HashSet<Pet> petsHS = new HashSet<Pet>(pets);
display(pets.iterator());
display(petsLL.iterator());
display(petsHS.Iterator());
}
}


注:因为本人是android 开发,所以本文中涉及到的源码都为 sdk 中java.util包下的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息