美文网首页
集合常用的3种遍历方式

集合常用的3种遍历方式

作者: 御都 | 来源:发表于2019-05-16 08:23 被阅读0次

    1 迭代器 Iterator

    • 1.1 Iterator常用的3个方法
      bollean hasNext() 判断集合中指针指向的位置是否还有元素
      Object next() ,获取元素并指向下一个元素的位置,不要多次使用next(),调用一次指针就自动下移一个,特别是遍历的循环体中,只能调用一次该方法
      void remove() 删除集合中next()返回的元素
    • 1.2 while/for循环和迭代器结合使用实现集合元素的遍历
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;
    
    public class CollectionIterator3 {
        public static void main(String[] args) {
            Collection c = new ArrayList();
            c.add("hello");
            c.add("world");
            c.add("java");
            Iterator it = c.iterator();
            while(it.hasNext()){
                String s = (String)it.next();
                System.out.println("while "+s);
                
            }
            Iterator it2 = c.iterator();
            for(;it2.hasNext();){
                String s = (String)it2.next();
                System.out.println("for "+s);
            }
            System.out.println("当前集合元素为:"+c.toString());
        }
    }
    

    运行结果

    while hello
    while world
    while java
    for hello
    for world
    for java
    当前集合元素为:[hello, world, java]
    

    说明上面例子中for和while不能使用同一个iterator对象,因为在while循环中iterator已经返回最后一个元素,指针指向的下一个元素为空了,即hasNext()返回值为false,不能用该迭代器的hasNext()作为for循环的判断条件。

    2 转换为Object[]进行遍历

    package it.cast01;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;
    
    public class CollectionIterator3 {
        public static void main(String[] args) {
            Collection c = new ArrayList();
            c.add("hello");
            c.add("world");
            c.add("java");
            Object[] objs = c.toArray();
            for(int i=0;i<objs.length;i++){
                String s = (String)objs[i];
                System.out.println(s+"---"+s.length());
            }
            System.out.println("当前集合元素为:"+c.toString());
        }
    }
    

    运行结果

    hello---5
    world---5
    java---4
    当前集合元素为:[hello, world, java]
    

    3 使用增强for(foreach)实现遍历

    • 3.1 格式
      for(元素数据类型 变量 : 数组或者Collection集合) {
      使用变量即可,该变量就是元素
      }
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;
    
    public class CollectionIterator3 {
        public static void main(String[] args) {
            Collection c = new ArrayList();
            c.add("hello");
            c.add("world");
            c.add("java");
            Object[] objs = c.toArray();
            for(Object obj:c){
                String s = (String)obj;
                System.out.println(s+"---"+s.length());
            }
            System.out.println("当前集合元素为:"+c.toString());
        }
    }
    

    运行结果

    hello---5
    world---5
    java---4
    当前集合元素为:[hello, world, java]
    

    `注意·
    增强for有个缺点,如果集合或者数组为null,会报空指针异常(NullPointerException),在调用增强for时最好先做判断。通过反编译可以看到增强for是用iterator的for循环实现的,是iterator的替代,iterator也有这种空指针异常的问题。

    public static void main(String[] args) {
            ArrayList<String> alist = null;
            
            if(alist!=null)
            for(String s : alist){
                System.out.println(s);
            }
        }
    

    4说明

    • 4.1以上遍历的循环中,传入的是集合元素的值,更改元素的值的操作对集合无效;
              for(Object obj:c){
                String s = (String)obj;
                if(s.equals("java")){
                    s = "math";
                }
                System.out.println(s+"---"+s.length());
            }
            System.out.println("当前集合元素为:"+c.toString());
    

    运行结果,集合元素内容不变

    hello---5
    world---5
    math---4
    当前集合元素为:[hello, world, java]
    

    *4.2 并行修改异常ConcurrentModificationException
    4.2.1 迭代器和foreach(增强for)遍历的循环中,不能出现集合对象本身调用方法更改集合内容,否则运行会报错 java.util.ConcurrentModificationException(并修改异常)
    原因是--迭代器和foreach都是依赖集合而存在的,如果集合更改了,迭代器和增强for都不知道,所以就报并行修改异常。

            for(Object obj:c){
                String s = (String)obj;
                if(s.equals("java")){
                    s = "math";
                    c.add("home");
                }
                System.out.println(s+"---"+s.length());
            }
            System.out.println("当前集合元素为:"+c.toString());
        }
    

    运行结果

    hello---5
    world---5
    math---4
    Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
        at java.util.AbstractList$Itr.next(AbstractList.java:343)
        at it.cast01.CollectionIterator3.main(CollectionIterator3.java:14)
    

    4.2.2 解决办法
    A 使用普通for循环,在循环中根据判断集合对内容进行修改
    B 使用迭代器对集合内容进行修改,Iterator接口中没有该方法,它的子类ListIterator接口中提供add()
    详情请参考:https://www.jianshu.com/p/94b12cceb6c7中(二、3.3)
    4.3 一个集合对象的迭代器循环中多次使用next(),会出现java.util.NoSuchElementException异常。

    public class CollectionIterator3 {
        public static void main(String[] args) {
            Collection c = new ArrayList();
            Student s1 = new Student(10,"aa");
            Student s2 = new Student(10,"bb");
            Student s3 = new Student(10,"cc");
            Student s4 = new Student(10,"dd");
            Student s5 = new Student(10,"ee");
            c.add(s1);
            c.add(s2);
            c.add(s3);
            c.add(s4);
            c.add(s5);
            Iterator it = c.iterator();
            while(it.hasNext()){
                System.out.println(((Student)it.next()).getAge()+"----"
            +((Student)it.next()).getName());
            }
            System.out.println("当前集合元素为:"+c.toString());
        }
    }
    

    运行结果

    10----bb
    10----dd
    Exception in thread "main" java.util.NoSuchElementException
        at java.util.AbstractList$Itr.next(AbstractList.java:350)
        at it.cast01.CollectionIterator3.main(CollectionIterator3.java:23)
    
    

    4.4 迭代器的remove()能删除next()返回的元素,这也算是更改了集合的内容,不能用元素的值在进行迭代进行解释,遗留

    public class CollectionIterator3 {
        public static void main(String[] args) {
            Collection c = new ArrayList();
            Student s1 = new Student(10,"aa");
            Student s2 = new Student(10,"bb");
            Student s3 = new Student(10,"cc");
            Student s4 = new Student(10,"dd");
            Student s5 = new Student(10,"ee");
            c.add(s1);
            c.add(s2);
            c.add(s3);
            c.add(s4);
            c.add(s5);
            Iterator it = c.iterator();
            while(it.hasNext()){
                Student s = (Student)it.next();
                if(s.getName().equals("cc")){
                    it.remove();
                }
            }
            System.out.println("当前集合元素为:"+c.toString());
        }
    }
    

    运行结果

    当前集合元素为:[[aa,10], [bb,10], [dd,10], [ee,10]]
    

    相关文章

      网友评论

          本文标题:集合常用的3种遍历方式

          本文链接:https://www.haomeiwen.com/subject/ahavaqtx.html