迭代器的引出
在jdk1.5版本之前是没有 foreach的,然而1.5版本就加上了foreach,而引入的新的foreach功能并不是在jvm上进行改进的因为代价太高,甲骨文工程师想到了一个比较好的办法就是在编译器中引入迭代器的概念从而实现foreach遍历。
请看一段代码:
// 功能 使用HashSet存储、删除、遍历 几个学生的信息
HashSet<Student> hash = new HashSet<Student>();
hash.add(new Student("张三", 20));
hash.add(new Student("李四", 21));
hash.add(new Student("王二", 22));
hash.add(new Student("麻子", 23));
String st1 = "hello";
String st2 = "hello";
String st3 = st2;
System.out.println(st1 == st3);
// 删除一个姓名为张三的学生
String name1 = "张三";
boolean flag = true;
for (Student student : hash) {
String name2 = student.getName();
if(name1 == name2){
hash.remove(student);
flag = false;
break;
}
}
if(flag){
System.out.println("不存在");
}
for (Student s : hash) {
System.out.println(s);
}
而上面的代码在运行多次的时候会出现下列错误异常:
这个错误是在遍历集合的同时删除了集合中的数据,这种写法不保证线程安全
怎么解决?上面的写法是不同的人做了不同的事 解决办法就是让一个人即遍历又删除 这就引出了 迭代器
先看下迭代器的简单用法:
我先把迭代器比作导游 集合里存的都是景点
请看上面的红色箭头是从最开始位置出现 然后通过迭代器的next()一个个往下找
// 迭代器的用法
// 1、创建集合
ArrayList<String> al = new ArrayList<String>();
al.add("张三");
al.add("李四");
al.add("王二");
// 创建迭代器对象 注意这里创建迭代器不是用new 而是用集合的方法
Iterator<String> it = al.iterator();
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
改写异常之后的写法:
// 功能 使用HashSet存储、删除、遍历 几个学生的信息
HashSet<Student> hash = new HashSet<Student>();
hash.add(new Student("张三", 20));
hash.add(new Student("李四", 21));
hash.add(new Student("王二", 22));
hash.add(new Student("麻子", 23));
String st1 = "hello";
String st2 = "hello";
String st3 = st2;
System.out.println(st1 == st3);
// 删除一个姓名为张三的学生
String name1 = "张三";
boolean flag = true;
Iterator<Student> it = hash.iterator();
while(it.hasNext()){
Student s = it.next();
if(name1.equals(s.getName())){
it.remove();
flag = false;
break;
}
}
if(flag){
System.out.println("不存在");
}
for (Student s : hash) {
System.out.println(s);
}
迭代器的底层原理
根据图所示 为达到方法的统一性所有集合都是实现了Interable接口 通过实现接口的方法创建并返回一个Iterator对象
然后通过创建内部类实现Iterator 里所有的方法最终目的是为了统一所有集合中的方法名称一样