迭代器
迭代器iterator
迭代器是专门用来遍历集合的(数组中没有迭代器),而迭代器的代表是iterator
通过iterator()
方法: 用iterator对象指向获取到的集合的第一个位置,通过这个对象调用hasnext()判断当前值是否为空,通过对象调用next()方法来获取当前值,并将索引移动到下一个地方.一直取到后面为空的时候,所以你要做非空判断,通过while来遍历iterator对象
原理图
方法
例子1
// 创建一个ArrayList集合
ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Orange");
// 获取集合的迭代器
Iterator<String> iterator = list.iterator();
// 使用迭代器遍历集合中的元素
while (iterator.hasNext()) {
String element = iterator.next(); //跟IO字节输入流read()一样.一次读取一个,指针下移
System.out.println(element);
}
例子2
package Collection;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
public class Iterator迭代器 {
/* [注意迭代器Iterator是Collection的方法] 迭代器适用于遍历集合的专有方式
,而迭代器的 next()方法是用于获取当前元素的位置,并将迭代器对象指向下一个索引.
*/// Iterator迭代器的hasNext()用于判断当前元素是否为空,返回值boolean
public static void main(String[] args) {
Collection coll = new LinkedList(); //多态的表现,将接口Collection指向实现类的对象(父类的引用指向子类的对象)
// 创建一个迭代器 Iterator,这也是个接口,有两个抽象方法 public Object next() ,public boolean hasNext() coll.add("肖恩");
coll.add("阿甘");
coll.add("袁隆平");
coll.add("钱学森");
Iterator it = coll.iterator(); //将LinkedList集合转成iterator对象,就可以进行迭代器打印输出了
System.out.println(it.next());
System.out.println(it.next());
System.out.println(it.next());
System.out.println(it.next());
// System.out.println(it.next()); //这里会报错,取不到第五个值
// 这种方式不好,用循环(不知道多少次的while)
while (it.hasNext()) { //判断数据是否存在
String ele = (String) it.next(); //取出数据
System.out.println(ele);//打印数据
}
}
}
其他遍历方式
1. 增强for
增强for循环可以用来遍历集合和数组,而增强for循环就是迭代器Iterator的简写
格式
例子
package Collection;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
public class 增强for循环 {
//增强for循环可以用来遍历集合和数组,而增强for循环就是迭代器Iterator的简写
/* 格式: for(元素的数据类型 变量名 :数组/集合){ 方法体 }快捷方式: 集合对象.for
*/
public static void main(String[] args) {
Collection<String> coll = new LinkedList();
coll.add("小龙女");
coll.add("白鹿");
coll.add("告五人");
coll.add("卢冠廷");
for (String name: coll) {
System.out.println(name);
}
System.out.println("===================================");
String [] names = coll.toArray(new String[coll.size()]);
for( String name : names){
System.out.print(name+" ");
}
System.out.println("==========");
System.out.println(Arrays.toString(names));//打印这个数组
}
}
2.forEach()遍历
内部创建了一个匿名内部类Consumer类,它是一个函数式接口,得重写他的抽象方法accept()
而匿名内部类底层就是利用增强for遍历的方式将每个值传给accept(参数) ,打印出来
例子
package Collection;
import java.util.Collection;
import java.util.LinkedList;
import java.util.function.Consumer;
public class forEach遍历 {
public static void main(String[] args) {
Collection<String> coll = new LinkedList();
coll.add("小龙女");
coll.add("白鹿");
coll.add("告五人");
coll.add("卢冠廷");
System.out.println(coll);
System.out.println("================");
// 使用forEach遍历集合
//
coll.forEach(new Consumer<String>() { //Consumer是一个接口,有个抽象方法accept,而且Consumer是一个函数式接口,可用lambda
//这个匿名内部类Consumer里面利用for增强遍历把每个集合对应的值依次交给accept方法,再打印输入
@Override
public void accept(String name) {//
System.out.println(name);
}
});
System.out.println("================");
// 这里可以简化成lambda格式
coll.forEach(name-> System.out.println(name)); //这里out是一个对象,对象out调用println()方法,可以用实例引用来简化lambda
System.out.println("=======================");
coll.forEach(System.out::println);
}
}
并发修改异常
1. 迭代器指针异常
当我们使用集合的删除方法时 list.remove() , 因为list集合的特性,删除元素位置的后面元素会前移一格,而索引是依次指向下一个位置(不管是迭代器的it.next()方法,还是for i循环都会有这种情况发送 ,而for i循环可用i--回退,而迭代器也可以通过it.remove()回退索引位,而不是用list.remove()去删除 ),可以并发修改
2.for循环指针异常
可以并发修改
3. for增强指针异常
这里没有办法回退,因为增强for循环本身是迭代器的简化写法, 但用不了迭代器的remove()方法,所以这个无法并发修改
4. forEach
结合lambda语句遍历, 底层是增强for循环 ,所以也无法并发修改数据
当你的才华配不上你的野心,努力的时候到了!