我们会使用了集合类了,但是我们应该如何去遍历每种集合类呢?
这时候Iterator就对Collection底下 包括 Collection的共性抽取。
只要实现了这个三个方法就行了。hasNext()、next()、remove();
就能遍历集合了,叫迭代。、
为了所有集合都能使用(除了Map),所以在Collection接口中必须得实现一个方法就是iterator() 返回 Iterator的对象。
ListIterator
当我们要在迭代的时候,去增删,修改集合元素长度的时候,会产生异常。
列表迭代器是快速失败 的:在迭代器创建之后,如果从结构上对列表进行修改,除非通过列表迭代器自身的 remove 或 add 方法,其他任何时间任何方式的修改,列表迭代器都将抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不冒将来不确定的时间任意发生不确定行为的风险。
那我们应该调用ListIterator类里的方法来操作集合来进行增删。
如何调用呢?
public class DemoListIterator{ List<String> list = new LinkedList<String>(); public static void main(String [] args ){ list.add("a"); list.add("b"); list.add("c"); list.add("d"); ListIterator<String> iterator = list.listIterator(); while(iterator.hasNext()){ iterator.next(); iterator.set("java"); } } }
iterable
在jdk1.5版本后,就出现了加强foreach 循环,
public interface Iterable
实现这个接口允许对象成为 “foreach” 语句的目标。
原理是这样的。
是编译器做了优化,就看了下最终编译成的字节码
java代码
public class Iterable_eros { List<String> strings; public void display(){ for(String s : strings){ System.out.println(s); } } }
转换成字节码:
字节码
public void display (){ line0 : aload_0 getfield java.util.List my.lang.Iterable_eros.strings invokeinterface java.util.Iterator java.util.List.iterator() 1 astore_2 goto line30 line13 : aload_2 invokeinterface java.lang.Object java.util.Iterator.next() 1 checkcast java.lang.String astore_1 line23 : getstatic java.io.PrintStream java.lang.System.out aload_1 line27 : invokevirtual void java.io.PrintStream.println(java.lang.String) line30 : aload_2 invokeinterface boolean java.util.Iterator.hasNext() 1 ifne line13 line39 : return
可以看到,foreach语法最终被编译器转为了对Iterator.next()的调用。而作为使用者的我们, jdk并没用向我们暴露这些细节,我们甚至不需要知道Iterator的存在,认识到jdk的强大之处了吧。
具体解释