对 Collection 进行迭代的类,称其为迭代器。还是面向工具的思想,专业工具做专业的事情,迭代器便是专门取出凑集元素的工具。但是该工具比较分外,不能直接创建工具(通过new),该工具因此内部类的形式存在于每个凑集类的内部。
如何获取迭代器?Collection接口中定义了获取凑集类迭代器的方法(iterator()),以是所有的Collection体系凑集都可以获取自身的迭代器。
正是由于每一个容器都有取出元素的功能。这些功能定义都一样,只不过实现的详细办法不同(由于每一个容器的数据构造不一样)以是对共性的取出功能进行了抽取,从而涌现了Iterator接口。而每一个容器都在其内部对该接口进行了内部类的实现。也便是将取出办法的细节进行封装。
1.1.1. Iterable
Jdk1.5之后添加的新接口, Collection的父接口. 实现了Iterable的类便是可迭代的.并且支持增强for循环。该接口只有一个方法即获取迭代器的方法iterator()可以获取每个容器自身的迭代器Iterator。(Collection)凑集容器都须要获取迭代器(Iterator)于是在5.0后又进行了抽取将获取容器迭代器的iterator()方法放入到了Iterable接口中。Collection接口进程了Iterable,以是Collection体系都具备获取自身迭代器的方法,只不过每个子类凑集都进行了重写(由于数据构造不同)
1.1.2. IteratorIterator iterator() 返回该凑集的迭代器工具
该类紧张用于遍历凑集工具,该类描述了遍历凑集的常见方法1:java.lang. Itreable ---| Itreable 接口 实现该接口可以利用增强for循环---| Collection 描述所有凑集共性的接口---| List接口 可以有重复元素的凑集---| Set接口 不可以有重复元素的凑集
public interface Iterable<T>
Itreable 该接口仅有一个方法,用于返回凑集迭代器工具。
1: Iterator<T> iterator() 返回凑集的迭代器工具
Iterator接口定义的方法
Itreator 该接口是凑集的迭代器接口类,定义了常见的迭代方法1:boolean hasNext() 判断凑集中是否有元素,如果有元素可以迭代,就返回true。2: E next() 返回迭代的下一个元素,把稳: 如果没有下一个元素时,调用next元素会抛出NoSuchElementException3: void remove()从迭代器指向的凑集中移除迭代器返回的末了一个元素(可选操作)。
思考:为什么next方法的返回类型是Object的呢? 为了可以吸收任意类型的工具,那么返回的时候,不知道是什么类型的就定义为object
1.1.3. 迭代器遍历1:while循环
public static void main(String[] args) {ArrayList list = new ArrayList();// 增加:add() 将指定工具存储到容器中list.add("打算机网络");list.add("当代操作系统");list.add("java编程思想");list.add("java核心技能");list.add("java措辞程序设计");System.out.println(list);Iterator it = list.iterator();while (it.hasNext()) {String next = (String) it.next();System.out.println(next);}}
2:for循环
import java.util.ArrayList;import java.util.Iterator;public class Demo2 {public static void main(String[] args) {ArrayList list = new ArrayList();// 增加:add() 将指定工具存储到容器中list.add("打算机网络");list.add("当代操作系统");list.add("java编程思想");list.add("java核心技能");list.add("java措辞程序设计");System.out.println(list);for (Iterator it = list.iterator();it.hasNext();) {//迭代器的next方法返回值类型是Object,以是要记得类型转换。String next = (String) it.next();System.out.println(next);}}}
须要取出所有元素时,可以通过循环,java 建议利用for 循环。由于可以对内存进行一下优化。
3:利用迭代器清空凑集
public class Demo1 {public static void main(String[] args) {Collection coll = new ArrayList();coll.add("aaa");coll.add("bbb");coll.add("ccc");coll.add("ddd");System.out.println(coll);Iterator it = coll.iterator();while (it.hasNext()) {it.next();it.remove();}System.out.println(coll);}}
细节一:
如果迭代器的指针已经指向了凑集的末端,那么如果再调用next()会返回NoSuchElementException非常
import java.util.ArrayList;import java.util.Iterator;public class Demo2 {public static void main(String[] args) {ArrayList list = new ArrayList();// 增加:add() 将指定工具存储到容器中list.add("打算机网络");list.add("当代操作系统");list.add("java编程思想");list.add("java核心技能");list.add("java措辞程序设计");System.out.println(list);Iterator it = list.iterator();while (it.hasNext()) {String next = (String) it.next();System.out.println(next);}// 迭代器的指针已经指向了凑集的末端// String next = (String) it.next();// java.util.NoSuchElementException}}
细节二:
如果调用remove之前没有调用next是不合法的,会抛出IllegalStateException
import java.util.ArrayList;import java.util.Iterator;public class Demo2 {public static void main(String[] args) {ArrayList list = new ArrayList();// 增加:add() 将指定工具存储到容器中list.add("打算机网络");list.add("当代操作系统");list.add("java编程思想");list.add("java核心技能");list.add("java措辞程序设计");System.out.println(list);Iterator it = list.iterator();while (it.hasNext()) {// 调用remove之前没有调用next是不合法的// it.remove();// java.lang.IllegalStateExceptionString next = (String) it.next();System.out.println(next);}}}
4:迭代器事理
查看ArrayList源码
private class Itr implements Iterator<E> {int cursor = 0;int lastRet = -1;int expectedModCount = modCount;public boolean hasNext() {return cursor != size();}public E next() {checkForComodification();try {E next = get(cursor);lastRet = cursor++;return next;} catch (IndexOutOfBoundsExceptione) {checkForComodification();throw new NoSuchElementException();}}public void remove() {if (lastRet == -1)throw new IllegalStateException();checkForComodification();try {AbstractList.this.remove(lastRet);if (lastRet < cursor)cursor--;lastRet = -1;expectedModCount = modCount;} catch (IndexOutOfBoundsExceptione) {throw new ConcurrentModificationException();}}}
5:把稳在对凑集进行迭代过程中,不许可涌现迭代器以外的对元素的操作,由于这样会产生安全隐患,java会抛出非常并发修正非常(ConcurrentModificationException),普通迭代器只支持在迭代过程中的删除动作。
把稳: ConcurrentModificationException: 当一个凑集在循环中即利用引用变量操作凑集又利用迭代器操作凑集工具, 会抛出该非常。
import java.util.ArrayList;import java.util.Collection;import java.util.Iterator; public class Demo1 {public static void main(String[] args) {Collectioncoll = new ArrayList();coll.add("aaa");coll.add("bbb");coll.add("ccc");coll.add("ddd");System.out.println(coll);Iterator it = coll.iterator();while (it.hasNext()) {it.next();it.remove();coll.add("abc"); // 涌现了迭代器以外的对元素的操作}System.out.println(coll);}}
如果是List凑集,想要在迭代中操作元素可以利用List凑集的特有迭代器ListIterator,该迭代器支持在迭代过程中,添加元素和修正元素。
1.1.4. List特有的迭代器ListIteratorpublic interface ListIterator extends Iterator
ListIterator<E> listIterator()
---|IteratorhasNext()next()remove()------| ListIterator Iterator子接口List专属的迭代器add(E e) 将指定的元素插入列表(可选操作)。该元素直接插入到next 返回的下一个元素的前面(如果有)voidset(E o) 用指定元素更换 next 或 previous 返回的末了一个元素hasPrevious() 逆向遍历列表,列表迭代器有多个元素,则返回true。previous() 返回列表中的前一个元素。
Iterator在迭代时,只能对元素进行获取(next())和删除(remove())的操作。
对付 Iterator 的子接口ListIterator 在迭代list 凑集时,还可以对元素进行添加
(add(obj)),修正set(obj)的操作。
import java.util.ArrayList;import java.util.ListIterator;public class Demo2 {public static void main(String[] args) {ArrayList list = new ArrayList();// 增加:add() 将指定工具存储到容器中list.add("打算机网络");list.add("当代操作系统");list.add("java编程思想");list.add("java核心技能");list.add("java措辞程序设计");System.out.println(list);// 获取List专属的迭代器ListIterator lit = list.listIterator();while (lit.hasNext()) {String next = (String) lit.next();System.out.println(next);}}}
倒序遍历
import java.util.ArrayList;import java.util.ListIterator;public class Demo2 {public static void main(String[] args) {ArrayList list = new ArrayList();// 增加:add() 将指定工具存储到容器中list.add("打算机网络");list.add("当代操作系统");list.add("java编程思想");list.add("java核心技能");list.add("java措辞程序设计");System.out.println(list);// 获取List专属的迭代器ListIterator lit = list.listIterator();while (lit.hasNext()) {String next = (String) lit.next();System.out.println(next);}System.out.println("");while (lit.hasPrevious()) {String next = (String)lit.previous();System.out.println(next);}}}
Set方法:用指定元素更换 next 或 previous 返回的末了一个元素
import java.util.ArrayList;import java.util.ListIterator;public class Demo2 {public static void main(String[] args) {ArrayList list = new ArrayList();// 增加:add() 将指定工具存储到容器中list.add("打算机网络");list.add("当代操作系统");list.add("java编程思想");list.add("java核心技能");list.add("java措辞程序设计");System.out.println(list);ListIterator lit = list.listIterator();lit.next(); // 打算机网络lit.next();// 当代操作系统System.out.println(lit.next()); // java编程思想//用指定元素更换 next 或 previous 返回的末了一个元素lit.set("平凡的天下");// 将java编程思想更换为平凡的天下System.out.println(list);}}
add方法将指定的元素插入列表,该元素直接插入到 next 返回的元素的后
public class Demo2 {public static void main(String[] args) {ArrayList list = new ArrayList();// 增加:add() 将指定工具存储到容器中list.add("打算机网络");list.add("当代操作系统");list.add("java编程思想");list.add("java核心技能");list.add("java措辞程序设计");System.out.println(list);ListIterator lit = list.listIterator();lit.next(); // 打算机网络lit.next(); // 当代操作系统System.out.println(lit.next()); // java编程思想// 将指定的元素插入列表,该元素直接插入到 next 返回的元素的后lit.add("平凡的天下");// 在java编程思想后添加平凡的天下System.out.println(list);}}