java容器系列 —— 从Iterator说起

工作了一段时间,越发觉得基础的东西很重要,尤其是想要提升自生代码质量的时候。所以在工作之余,又开始看《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包下的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值