金榜题名,前程似锦
—— 24.5.27
一、迭代器的介绍和使用
1.概述
Iterator接口
2.主要作用
遍历集合
3.获取
Collection中的方法:
Iterator<E> iterator()
4.方法
boolean hasNext() —> 判断集合中有没有下一个元素
E.next() —> 获取下一个元素
5.示例
import java.util.ArrayList; import java.util.Iterator; public class Demo224Iterator { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("慕容云海"); list.add("楚雨寻"); list.add("端木磊"); list.add("上官瑞谦"); list.add("叶烁"); // 获取迭代器对象 Iterator<String> iterator = list.iterator(); // 判断有没有下一次迭代 while (iterator.hasNext()){ String element = iterator.next(); System.out.println(element); } } }
注意:next方法在使用时,不要连续多次使用,否则会出现:NoSuchElementException:没有可操作的元素异常
二、迭代器迭代过程
int cursor; // 下一个元素索引位置
int lastRet = -1; // 上一个元素索引位置
三、迭代器底层原理
1.获取Iterator的时候如何获取:
Iterator iterator = list.iterator()
Iterator是一个接口,等号的右边是它的实现类对象
2.Iterator接收的是哪个实现类对象?
ArrayList中的内部类Itr对象(各集合的内部类对象不一样)
注意:只有ArrayList使用迭代器的时候Iterator接口才会指向Itr,其他的集合使用迭代器,Iterator就指向的不是Itr
package S83SetFrame; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; public class Demo224Iterator { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("慕容云海"); list.add("楚雨荨"); list.add("端木磊"); list.add("上官瑞谦"); list.add("叶烁"); // 获取迭代器对象 Iterator<String> iterator = list.iterator(); // 判断有没有下一次 while (iterator.hasNext()){ String element = iterator.next(); System.out.println(element); } HashSet<String> set = new HashSet<>(); Iterator<String> iterator1 = set.iterator(); } }
四、并发修改异常(了解)
需求:
定义一个集合,存储 唐僧,孙悟空,猪八戒,沙僧,遍历集合,如果遍历到猪八戒,往集合中添加一个白龙马
package S83SetFrame; import java.util.ArrayList; import java.util.Iterator; public class DemoSetFramePractice { public static void main(String[] args) { // 需求:定义一个集合,存储 唐僧,孙悟空,猪八戒,沙僧,遍历集合,如果遍历到猪八戒,往集合中添加一个白龙马 ArrayList<String> list = new ArrayList<>(); list.add("唐僧"); list.add("孙悟空"); list.add("猪八戒"); list.add("沙僧"); // 遍历集合 Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String next = iterator.next(); // 字符串比较,常量放在前,用equals函数比较 if("猪八戒".equals(next)){ list.add("白龙马"); } } System.out.println(list); } }
结论:当预期操作次数和实际操作次数不相等了,会出现"并发修改异常”
最终结论:我们调用了add方法,而add方法底层只给modcount++,但是再次调用next方法的时候,并没有给修改后的modcount重新赋值给expectedModcount,导致next方法底层的判断判断出实际操作次数和预期操作次数不相等了,所以抛出了"并发修改异常"
package S83SetFrame; import java.util.ArrayList; import java.util.Iterator; import java.util.ListIterator; public class DemoSetFramePractice { public static void main(String[] args) { // 需求:定义一个集合,存储 唐僧,孙悟空,猪八戒,沙僧,遍历集合,如果遍历到猪八戒,往集合中添加一个白龙马 ArrayList<String> list = new ArrayList<>(); list.add("唐僧"); list.add("孙悟空"); list.add("猪八戒"); list.add("沙僧"); // 遍历集合 ListIterator<String> listIterator = list.listIterator(); while (listIterator.hasNext()) { String next = listIterator.next(); // 字符串比较,常量放在前,用equals函数比较 if("猪八戒".equals(next)){ listIterator.add("白龙马"); } } System.out.println(list); } }
使用迭代器迭代集合的过程中,不要随意修改集合长度,容易出现并发修改异常