什么是迭代器
从两方面来说,从底层原理上来说是大同小异的,底层通过hasnext()方法判断当前当前指向是否有元素,而指针一开始就会指向第一个元素。如果有,就会再执行next()方法,取出当前游标,并向后移一位;如果hasnext()方法返回为null,就说明不存在下一个元素,就会迭代结束。针对不同集合,会有一些细节不同,(比如HashMap就要考虑到红黑树里的取出顺序)。再底层则是采用C语言的指针原理。
在应用层面上,迭代器就是用来遍历的。所有的单列集合都可以使用迭代器,因为他们都继承了Iterable接口,这个接口里的Iterator方法可以返回一个Iterator对象,这个Iterator对象就是迭代器对象,底层针对不同类型的集合都写了不同的实现类,所以集合可以直接使用迭代器进行遍历查询。这种只需要提供一种方法(iterator方法)访问一个容器对象中各个元素,而又不暴露该对象的内部细节的方式就是迭代器设计模式。
但要注意的是,如果用的是直接使用增强for和用迭代器方式(iterator)是不一样的,后者可以直接修改、删除原数据,但增强for是引用了一个第三方变量进行遍历,只适合单纯遍历。
iterator是自动取下一个,如果需要倒着遍历怎么办?
List集合可以使用迭代器倒着遍历,ListIterator有previous()方法和hasprevious()方法,可以自动指向并取出上一个元素。Set集合不能用迭代器倒着遍历,但可以根据它的大小顺序倒着取出。
使用foreach、iterator、for在有什么区别?效率上哪个更高?
区别上:
普通for循环一般用来处理比较简单的有序的,可预知大小的集合或数组.
foreach可用于遍历任何集合或数组,而且操作简单易懂,唯一的不好就是需要了解集合内部类型,它的底层有函数式编程注解 @FunctionalInterface,也就是说它可以进行Lamda形式简写。
iterator是最强大的,他可以随时修改或者删除集合内部的元素,并且是在不需要知道元素和集合的类 型的情况下进行的,当你需要对不同的容器实现同样的遍历方式时,迭代器是最好的选择!
至于增强for和iterator其实是一样的,增强for编译后的.class文件中,就是iterator,所以二者除了写法是用第三方参数来表示,效率上没有任何区别。
效率上:
这个需要多方考虑,比如普通for循环用在数组是遍历最快的,它是直接获取数据,但普通for不能用在不知道长度的集合中,这就需要用iterator或者foreach,相对来说,iterator效率会高于foreach,因为foreach在访问过程中产生一个额外的Enumerator对象,这个对象会进行版本检查处理,所以它是线安全的。
对于ArrayList来说,它是通过一个数组实现的,可以随机存取;但是LinkedList是通过链表实现的,当要遍历依个取出时,for循环时要取的每个元素都必须从头开始遍历,而iterator遍历则从头开始,边遍历边取,取完只需要一次遍历,所以for循环需要的时间远远超过for循环。
对于数组来说,for和foreach循环效率差不多,但是对于链表来说,for循环效率明显比foreach低。