对于数组我们是使用下标来进行处理的:
- int[] arrays = new int[10];
- for(int i = 0 ; i < arrays.length ; i++){
- int a = arrays[i];
- //do something
- }
对于ArrayList是这么处理的:
- List<String> list = new ArrayList<String>();
- for(int i = 0 ; i < list.size() ; i++){
- String string = list.get(i);
- //do something
- }
对于这两种方式,我们总是都事先知道集合的内部结构,访问代码和集合本身是紧密耦合的,无法将访问逻辑从集合类和客户端代码中分离出来。同时每一种集合对应一种遍历方法,客户端代码无法复用。 在实际应用中如何需要将上面将两个集合进行整合是相当麻烦的。所以为了解决以上问题,Iterator模式腾空出世,它总是用同一种逻辑来遍历集合。使得客户端自身不需要来维护集合的内部结构,所有的内部状态都由Iterator来维护。客户端从不直接和集合类打交道,它总是控制Iterator,向它发送"向前","向后","取当前元素"的命令,就可以间接遍历整个集合。
上面只是对Iterator模式进行简单的说明,下面我们看看Java中Iterator接口,看他是如何来进行实现的。
一、java.util.Iterator
在Java中Iterator为一个接口,它只提供了迭代了基本规则,在JDK中他是这样定义的:对 collection 进行迭代的迭代器。迭代器取代了 Java Collections Framework 中的 Enumeration。迭代器与枚举有两点不同:
1、迭代器允许调用者利用定义良好的语义在迭代期间从迭代器所指向的 collection 移除元素。
2、方法名称得到了改进。
其接口定义如下:
- public interface Iterator {
- boolean hasNext();
- Object next();
- void remove();
- }
其中:
Object next():返回迭代器刚越过的元素的引用,返回值是Object,需要强制转换成自己需要的类型
boolean hasNext():判断容器内是否还有可供访问的元素
void remove():删除迭代器刚越过的元素
对于我们而言,我们只一般只需使用next()、hasNext()两个方法即可完成迭代。如下:
- Iterator iterator = list.iterator();
- while(iterator.hasNext()){
- String string = iterator.next();
- }
总结:
Iterator遍历集合元素有以下几个特点:
- Iterator遍历集合元素的过程中不允许线程对集合元素进行修改,否则会抛出ConcurrentModificationEception的异常。
- Iterator遍历集合元素的过程中可以通过remove方法来移除集合中的元素。
- Iterator必须依附某个Collection对象而存在,Iterator本身不具有装载数据对象的功能。
- Iterator.remove方法删除的是上一次Iterator.next()方法返回的对象。
- 强调以下next()方法,该方法通过游标指向的形式返回Iterator下一个元素。
Iterator的常用方法:
- boolean hasNext() ;判断迭代器中是否还有下一个元素,有则返回true
- Object next(); 返回迭代器中下一个元素
- void remove() ; 删除集合里上一个next方法调用的时候返回的对象元素
- void forEachRemaining(Consumer action) ;使用Lambdda表达式的形式输出Iterator中所以的元素。注意该方法其实是间接调用next()方法进行遍历,所以再次是next()方法的时候Iterator中的对象已经被遍历完了。