对于Collection类下的集合如各类List各类Set,用于实现这些集合的数据结构各不相同,好比数组实现的ArrayList、链表实现的LinkedList,当客户端知道要使用的集合的底层结构的时候能够选择相应的遍历方式。java
好比客户端知道ArrayList是用数组实现的,可使用遍历数组的方式遍历ArrayList。若是客户端须要遍历的容器类型发生了变换可能就不能或者不适合使用先前的遍历方式,好比若是把ArrayList换成LinkedList,虽然仍然可使用这种方式遍历但性能大大下降;若是换成某个set,甚至不能使用这种方式遍历。设计模式
ArrayList<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); }
为了提升代码的通用性减少耦合性,在客户端和容器之间新增了一个新的角色:迭代器,迭代器负责屏蔽了各类Collection实现类的区别,采用一样的迭代器语法能够遍历Collection的全部子类,这样以来客户端的代码无需关心集合类的具体实现。数组
Iterator<Integer> iterator = list.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } Iterator<Integer> linkIterator = list2.iterator(); while (linkIterator.hasNext()){ System.out.println(linkIterator.next()); } Iterator<Integer> setIterator = set.iterator(); while (setIterator.hasNext()){ System.out.println(setIterator.next()); }
迭代器往小了说是一种遍历集合的方式,往大了说他也是一种设计模式。数据结构
能够猜出迭代器应该是某种接口,并且是应该靠近Collection继承体系顶层的接口,由于Collection集合下的全部类是通用的。性能
public interface Iterable<T> { Iterator<T> iterator();
default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } default Spliterator<T> spliterator() { return Spliterators.spliteratorUnknownSize(iterator(), 0); } }
iterable接口中第一个方法用来返回iterator对象,两者的名字很像。从英语语法的角度分析iterable是一个形容词表明实现了该接口的对象有可迭代的能力,iterator是一个名词是具体迭代的执行者又称迭代器。实现了iterable接口的集合对象经过返回的iterator实现了对该集合的迭代。剩下两个方法的jdk-1.8中新增的,它们使用default关键字修饰。default关键字容许在接口中定义方法,且不要求实现了该接口的类实现该方法。 ui
package java.util; import java.util.function.Consumer; /** public interface Iterator<E> { boolean hasNext();
E next();
default void remove() { throw new UnsupportedOperationException("remove"); } default void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); while (hasNext()) action.accept(next()); } }
关注的重点是iterator方法,hasNext方法用于判断集合中是否存在下一个元素,next用于取出下一个元素;剩下的两个default修饰的方法是jdk-1.8新增的。this