迭代器

迭代器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循环 ,所以也无法并发修改数据

posted @ 2025-01-20 01:08  加油酱  阅读(7)  评论(0)    收藏  举报