当遍历集合或者数组时,通常用for循环来遍历,这种遍历方式效率低下,本文介绍一种迭代器能够提高效率,快速遍历!
首先,要知道迭代器是什么?
迭代的概念
迭代:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续再判断,如果还有就再取出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。
获取迭代器对象
Collection集合提供了一个获取迭代器的方法:
public Iterator iterator()
: 获取集合对应的迭代器,用来遍历集合中的元素的。
Iterator接口的常用方法
public E next()
:返回迭代的下一个元素。public boolean hasNext()
:如果仍有元素可以迭代,则返回 true。
案例演示
public class IteratorDemo {
public static void main(String[] args) {
// 创建一个Collection集合对象,指定集合中元素的类型为String
Collection<String> coll = new ArrayList<>();
// 往集合中添加元素: public boolean add(E e)
coll.add("李冰冰");
coll.add("范冰冰");
coll.add("高圆圆");
coll.add("陈圆圆");
// 遍历coll集合中的元素:使用Collection集合中的迭代器
// 获取coll集合对应的迭代器
Iterator<String> it = coll.iterator();
// 循环使用迭代器进行判断
while (it.hasNext()) {
// 使用迭代器取出元素
String next = it.next();
System.out.println("取出来的元素:"+next);
}
System.out.println("源集合:"+coll);// 源集合:[李冰冰, 范冰冰, 高圆圆, 陈圆圆]
}
}
迭代器的常见问题
常见问题一
-
在进行集合元素获取时,如果集合中已经没有元素可以迭代了,还继续使用迭代器的next方法,将会抛出java.util.NoSuchElementException没有集合元素异常。
public static void main(String[] args) throws Exception{ Collection<String> coll = new ArrayList<>(); coll.add("李冰冰"); coll.add("范冰冰"); coll.add("高圆圆"); coll.add("陈圆圆"); Iterator<String> it = coll.iterator(); while (it.hasNext()) { String s = it.next(); System.out.println(s);//正确 } System.out.println("====================="); System.out.println(it.next());//集合中已经没有元素可以迭代了 报异常 }
-
解决办法: 如果还需要重新迭代,那么就重新获取一个新的迭代器对象进行操作
常见问题二
-
在进行集合元素迭代时,如果添加或移除集合中的元素 , 将无法继续迭代 , 将会抛出ConcurrentModificationException并发修改异常.
public static void main(String[] args) throws Exception{ Collection<String> coll = new ArrayList<>(); coll.add("李冰冰"); coll.add("范冰冰"); coll.add("高圆圆"); coll.add("陈圆圆"); Iterator<String> it = coll.iterator(); while (it.hasNext()) { String s = it.next(); System.out.println(s); //coll.add("章子怡");// 报异常 //coll.remove(s);// 报异常 it.remove(); } System.out.println("====================="+coll); }
迭代器的实现原理
讲解:
在之前案例已经完成了Iterator遍历集合的整个过程。当遍历集合时,首先通过调用t集合的iterator()方法获得迭代器对象,然后使用hashNext()方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取出,否则说明已到达了集合末尾,停止遍历元素。
**Iterator迭代器对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素。**在调用Iterator的next方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器的next方法后,迭代器的索引会向后移动一位,指向第一个元素并将该元素返回,当再次调用next方法时,迭代器的索引会指向第二个元素并将该元素返回,依此类推,直到hasNext方法返回false,表示到达了集合的末尾,终止对元素的遍历。
下图是迭代器迭代时图解:
知道了迭代器原理,明白了怎么进行迭代,接下来介绍一个循环:
增强for循环
讲解:
增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。
格式:
for(元素的数据类型 变量名 : Collection集合or数组){
//写操作代码
}
它用于遍历Collection和数组。通常只进行遍历元素,不要在遍历的过程中对集合元素进行增删操作。
代码演示
public class Test {
public static void main(String[] args) {
// 增强for循环遍历集合
Collection<String> col = new ArrayList<>();
// 添加元素
col.add("张柏芝");
col.add("邱淑贞");
col.add("王祖贤");
col.add("关之琳");
for (String name : col) {
System.out.println("name:" + name);
}
System.out.println("==========================================");
// 增强for循环遍历数组
String[] arr = {"张柏芝",
"邱淑贞",
"王祖贤",
"关之琳"};
for (String name : arr) {
System.out.println("name:"+name);
}
}
}
tips:
增强for循环必须有被遍历的目标,目标只能是Collection或者是数组;
增强for(迭代器)仅仅作为遍历操作出现,不能对集合进行增删元素操作,否则抛出ConcurrentModificationException并发修改异常