迭代器
不同java集合(容器)的內(nèi)部結(jié)構(gòu)是不一樣的,如果為每種容器都單獨(dú)實(shí)現(xiàn)一種遍歷方法十分麻煩,為了簡化遍歷容器的操作,所以推出了java迭代器(Iterator)
通過java迭代器,我們可以用統(tǒng)一的方法實(shí)現(xiàn)對容器的遍歷,極大地簡化了操作.
迭代器接口
1.java.util.Iterator接口
public interface Iterator<E> { //查詢?nèi)萜髦惺欠翊嬖谙乱粋€元素 boolean hasNext(); //返回下一個元素 //注意 : 在一次循環(huán)中,只能用一次next(),重復(fù)調(diào)用會返回再下面的元素. E next(); //把元素從容器中移除 //注意 : 要用迭代器的remove()方法,不要用容器的remove()方法.否則會發(fā)生異常 default void remove() { throw new UnsupportedOperationException("remove"); } //1.8新增默認(rèn)方法,以后再講 default void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); while (hasNext()) action.accept(next()); } }
2.java.util.Iterable
public interface Iterable<T> { //容器可以通過此方法,返回該容器的迭代器. Iterator<T> iterator(); //1.8新增,先不講 default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } //1.8新增,先不講 default Spliterator<T> spliterator() { return Spliterators.spliteratorUnknownSize(iterator(), 0); } }
Collection<E>接口繼承了Iterable<T>接口,而Iterable接口含有iterator()方法,所以 :
所有繼承自Collection<E>的容器,都實(shí)現(xiàn)了iterator()方法,從而通過此方法獲得各自容器的迭代器!
如何使用迭代器遍歷集合
List<String> list =new ArrayList<String>(); //給list添加元素的過程省略...... Iterator<String> listIterator = list.iterator(); while(listIterator.hasNext()) { //一次循環(huán)中只能調(diào)用一次next()方法!否則循環(huán)就亂套了! //因?yàn)槊看握{(diào)用next()都會獲取下一個元素. String next = listIterator.next(); if("bingo".equals(next)) { //只能通過迭代器刪除元素,用集合的remove()方法會發(fā)生異常! listIterator.remove(); //?這是錯誤方法? //list.remove(next); }else { System.out.println(next); } } System.out.println(list);
如果遍歷的是Map,那么用Map的entrySet()方法獲得Set<Entry<K, V>>,通過Set來獲取迭代器!(Map.Entry是一個鍵值對)
//Map通過entrySet()方法獲取Set,再獲取Set的迭代器 Iterator<Entry<Integer, String>> iterator =map.entrySet().iterator(); //之后的操作同上.
用Map.Entry的getKey()方法獲取鍵,getValue()方法獲取值.
ListIterator和Iterator的區(qū)別
迭代List集合時,推薦使用ListIterator
1. iterator()方法在set和list接口中都有定義,但是ListIterator()僅存在于list接口中(或?qū)崿F(xiàn)類中);
2. ListIterator有add()方法,可以向List中添加對象,而Iterator不能
3. ListIterator和Iterator都有hasNext()和next()方法,可以實(shí)現(xiàn)順序向后遍歷,但是ListIterator有hasPrevious()和previous()方法,可以實(shí)現(xiàn)逆向(順序向前)遍歷。Iterator就不可以。
4. ListIterator可以定位當(dāng)前的索引位置,nextIndex()和previousIndex()可以實(shí)現(xiàn)。Iterator沒有此功能。
5. 都可實(shí)現(xiàn)刪除對象,但是ListIterator可以實(shí)現(xiàn)對象的修改,set()方法可以實(shí)現(xiàn)。Iierator僅能遍歷,不能修改?! ?/p>
因?yàn)長istIterator的這些功能,可以實(shí)現(xiàn)對LinkedList等List數(shù)據(jù)結(jié)構(gòu)的操作。其實(shí),數(shù)組對象也可以用迭代器來實(shí)現(xiàn)。
為什么迭代器遍歷時不能用集合的remove()方法刪除元素?
會發(fā)生異常,具體以后再寫.
for增強(qiáng)循環(huán)
for增強(qiáng)循環(huán)實(shí)際上內(nèi)部也是使用的迭代器進(jìn)行遍歷.所以for增強(qiáng)循環(huán)在遍歷集合時也不能刪除元素(用集合的remove()方法)
for循環(huán)和迭代器誰更快?
主要看遍歷的集合的數(shù)據(jù)結(jié)構(gòu)是否合適 :
for循環(huán)依據(jù)索引來遍歷對象,所以在隨機(jī)訪問中比較快(比如ArrayList)
迭代器的next()采用的是順序訪問方法,所以在順序訪問的集合中速度更快(比如LinkedList)