java容器系列 —— 从Iterator说起
2016-04-18 11:40
405 查看
工作了一段时间,越发觉得基础的东西很重要,尤其是想要提升自生代码质量的时候。所以在工作之余,又开始看《JAVA编程思想》这本书,感觉收获颇丰,尤其是在看java容量类相关章节时,还参照了相关源码。为了与大家共享,同时加深自身理解,打算写成一个系列,有任何错误纰漏之处望指正。
想了很久,打算从Iterator说起。想必大家在开发过程中都使用过Iterator来遍历容器类,其实Iterator只是一个基于泛型的接口:
接口就只有上述几个方法,可以很容易从字面意思看出相应方法的含义。而在每个容器类中都定义了内部类来实现该接口,并通过Iterator()方法来返回对应内部类的一个对象实例,从而使我们可以调用接口中的方法来完成遍历。比如在抽象类AbstractList中有一个SimpleListIterator内部类:
在上述代码中,size(),get,remove等方法都是list接口中的方法。需要说明的一点就是expectedModCount这个参数,从上述代码里可以看出这个参数是在对象构造方法中赋值的,赋的值为modCount,在完成赋值操作后,expectedModCount在对象生命周期内就不会更改,只是在get和remove时将expectedModCount与modCount进行对比,如果两者不相等,则抛出ConcurrentModificationException异常,这个异常在线程不安全的容器类中很常见。而导致这个异常的原因正是在用Iterator变量容器类时,另外线程对容器类进行了结构性的修改,导致modCount发生变化。
通过上述代码可以看出,实现一个Iterator接口很简单。而Iterator作为一个接口,我们也可以在自定义的类中实现该接口,从而使其方法可以通过Iterator遍历我们自身类中的数据集。比如:
注:因为本人是android 开发,所以本文中涉及到的源码都为 sdk 中java.util包下的
想了很久,打算从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包下的
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法