iterator迭代器的使用

我想遍历一个ArrayList可以用for(int i=0;i<list.size();i++){list.get(i)}或者用for each即(for(Object o:list){sout(o)})

那么我想添加一个元素就可以直接:list.add(o);但是要注意的是:ArrayList和数组一样在内存中的存储是连续的,因此存储地址顺序向后添加

那么我想更改其中的一个元素怎么办?ArrayLikst 中有个set函数set(要更改的下标,要改成的内容);

那么我想删除一个元素呢?可能会说直接list.remove(o)或者list.remove(i);这只是删除一个元素,那么我想删除多个呢?用循环找出满足条件的元素然后remove,这是不对的。

其中有以下情况,其中做后一种为正确的

遍历删除List中的元素有很多种方法,当运用不当的时候就会产生问题。下面主要看看以下几种遍历删除List中元素的形式:

1.通过增强的for循环删除符合条件的多个元素

2.通过增强的for循环删除符合条件的一个元素

3.通过普通的for删除删除符合条件的多个元素

4.通过Iterator进行遍历删除符合条件的多个元素


Java代码   收藏代码
  1. /** 
  2.  * 使用增强的for循环 
  3.  * 在循环过程中从List中删除元素以后,继续循环List时会报ConcurrentModificationException 
  4.  */  
  5. public void listRemove() {  
  6.     List<Student> students = this.getStudents();  
  7.     for (Student stu : students) {  
  8.         if (stu.getId() == 2)   
  9.             students.remove(stu);  
  10.     }  
  11. }  

 

 

Java代码   收藏代码
  1. /** 
  2.  * 像这种使用增强的for循环对List进行遍历删除,但删除之后马上就跳出的也不会出现异常 
  3.  */  
  4. public void listRemoveBreak() {  
  5.     List<Student> students = this.getStudents();  
  6.     for (Student stu : students) {  
  7.         if (stu.getId() == 2) {  
  8.             students.remove(stu);  
  9.             break;  
  10.         }  
  11.     }  
  12. }  

 

 

Java代码   收藏代码
  1. /** 
  2.  * 这种遍历有可能会遗漏某个元素,因为删除元素后List的size在 
  3.  * 变化,元素的索引也在变化,比如你循环到第2个元素的时候你把它删了, 
  4.  * 接下来你去访问第3个元素,实际上访问到的是原先的第4个元素。当访问的元素 
  5.  * 索引超过了当前的List的size后还会出现数组越界的异常,当然这里不会出现这种异常, 
  6.  * 因为这里每遍历一次都重新拿了一次当前List的size。 
  7.  */  
  8. public void listRemove2() {  
  9.     List<Student> students = this.getStudents();  
  10.     for (int i=0; i<students.size(); i++) {  
  11.         if (students.get(i).getId()%3 == 0) {  
  12.             Student student = students.get(i);  
  13.             students.remove(student);  
  14.         }  
  15.     }  
  16. }  

 

 

Java代码   收藏代码
  1. /** 
  2.  * 使用Iterator的方式也可以顺利删除和遍历 
  3.  */  
  4. public void iteratorRemove() {  
  5.     List<Student> students = this.getStudents();  
  6.     System.out.println(students);  
  7.     Iterator<Student> stuIter = students.iterator();  
  8.     while (stuIter.hasNext()) {  
  9.         Student student = stuIter.next();  
  10.         if (student.getId() % 2 == 0)  
  11.             stuIter.remove();//这里要使用Iterator的remove方法移除当前对象,如果使用List的remove方法,则同样会出现ConcurrentModificationException  
  12.     }  
  13.     System.out.println(students);  
  14. }  

 

 

附完整代码如下:

 

Java代码   收藏代码
  1. import java.util.ArrayList;  
  2. import java.util.Iterator;  
  3. import java.util.List;  
  4.   
  5. public class ListRemove {  
  6.   
  7.     public static void main(String args[]) {  
  8.         ListRemove lr = new ListRemove();  
  9.         lr.listRemove();  
  10.         lr.listRemoveBreak();  
  11. //      lr.listRemove2();  
  12. //      lr.iteratorRemove();  
  13.     }  
  14.   
  15.     /** 
  16.      * 使用增强的for循环 
  17.      * 在循环过程中从List中删除元素以后,继续循环List时会报ConcurrentModificationException 
  18.      */  
  19.     public void listRemove() {  
  20.         List<Student> students = this.getStudents();  
  21.         for (Student stu : students) {  
  22.             if (stu.getId() == 2)   
  23.                 students.remove(stu);  
  24.         }  
  25.     }  
  26.       
  27.     /** 
  28.      * 像这种使用增强的for循环对List进行遍历删除,但删除之后马上就跳出的也不会出现异常 
  29.      */  
  30.     public void listRemoveBreak() {  
  31.         List<Student> students = this.getStudents();  
  32.         for (Student stu : students) {  
  33.             if (stu.getId() == 2) {  
  34.                 students.remove(stu);  
  35.                 break;  
  36.             }  
  37.         }  
  38.     }  
  39.       
  40.     /** 
  41.      * 这种不使用增强的for循环,每次重新获取list的size遍历的情况运行时不会报错,但是可能删除的结果是错的。 
  42.      */  
  43.     public void listRemove2() {  
  44.         List<Student> students = this.getStudents();  
  45.         for (int i=0; i<students.size(); i++) {  
  46.             if (students.get(i).getId()%2 == 0)  
  47.                 students.remove(i);  
  48.         }  
  49.     }  
  50.       
  51.     /** 
  52.      * 使用Iterator的方式也可以顺利删除和遍历 
  53.      */  
  54.     public void iteratorRemove() {  
  55.         List<Student> students = this.getStudents();  
  56.         System.out.println(students);  
  57.         Iterator<Student> stuIter = students.iterator();  
  58.         while (stuIter.hasNext()) {  
  59.             Student student = stuIter.next();  
  60.             if (student.getId() % 2 == 0)  
  61.                 stuIter.remove();  
  62.         }  
  63.         System.out.println(students);  
  64.     }  
  65.       
  66.     private List<Student> getStudents() {  
  67.         List<Student> students = new ArrayList<Student>() {  
  68.             {  
  69.                 int i = 0;  
  70.                 while (i++ < 10) {  
  71.                     Student student = new Student(i, "201200" + i, "name_" + i);  
  72.                     this.add(student);  
  73.                 }  
  74.             }  
  75.         };  
  76.         return students;  
  77.     }  
  78. }  

 

 

Java代码   收藏代码
  1. public class Student {  
  2.   
  3.     private int id;  
  4.     private String stuNo;  
  5.     private String name;  
  6.       
  7.     public Student() {  
  8.           
  9.     }  
  10.       
  11.     public Student(int id, String stuNo, String name) {  
  12.         this.id = id;  
  13.         this.stuNo = stuNo;  
  14.         this.name = name;  
  15.     }  
  16.   
  17.     public int getId() {  
  18.         return id;  
  19.     }  
  20.   
  21.     public void setId(int id) {  
  22.         this.id = id;  
  23.     }  
  24.   
  25.     public String getStuNo() {  
  26.         return stuNo;  
  27.     }  
  28.   
  29.     public void setStuNo(String stuNo) {  
  30.         this.stuNo = stuNo;  
  31.     }  
  32.   
  33.     public String getName() {  
  34.         return name;  
  35.     }  
  36.   
  37.     public void setName(String name) {  
  38.         this.name = name;  
  39.     }  
  40.   
  41.     @Override  
  42.     public String toString() {  
  43.         return "Student [id=" + id + ", name=" + name + ", stuNo=" + stuNo  
  44.                 + "]";  
  45.     }  
  46.       
  47. }  


import java.util.ArrayList;
import java.util.Iterator;

/**
 * Created by Administrator on 2015/11/23 0023.
 */
public class DeleteArray {
    public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<String>();
        for(int i=0;i<10;i++)
            list.add(i+"");
        System.out.println(list);

        listRemove5(list);
        System.out.println(list);

    }

    /**
     * 这是最正确的做法,用迭代器iterator来遍历删除,因为iterator是list的一个引用,因此它的操作会对list产生影响。
     * @param list
     */
    private static void listRemove5(ArrayList<String> list) {
        Iterator<String> it=list.iterator();
        int i=0;
        while(it.hasNext()){
            String str=it.next();
            if(i%2==0) {
                it.remove();
//                list.remove(it);
            }
            i++;
        }
    }

    /**
     * 简单的for循环删除,因为ArrayList在内存中的存储是顺序的,因此删除后后面的元素会自动向前移动,
     * 这样得到的结果就是错误的
     * @param list
     */
    private static void listRemove3(ArrayList<String> list) {

        for(int i=0;i<list.size();i++){
            if(i%2==0)
                list.remove(i);
        }
    }
    private static void listRemove4(ArrayList<String> list) {

        for(int i=0;i<list.size();i++){
            String str=list.get(i);
            if(i%2==0)
                list.remove(str);
        }
    }

    /**
     * 这样可以删除一个是不报错的
     */

    private static void listRemove2(ArrayList<String> list) {
        int i=0;
        for(String s:list){
            if(i%2==0)
                list.remove(s);
            break;
        }
    }

    /**
     * 这样循环删除是会报异常的
     * @param list
     */
    private static void listRemove1(ArrayList<String> list) {

        int i=0;
        for(String s:list){
            if(i%2==0)
                list.remove(s);
            i++;
        }
    }
}

但是后来我有测试了一个实例就是这个条件不是跟下标有关系的而是一个设定的条件:如:删除一个整型list中的偶数:

package deleteArrary;

import java.util.ArrayList;

/**
 * Created by Administrator on 2015/11/23 0023.
 */
public class Test {
    public static void main(String[] args) {
        ArrayList<Integer> list=new ArrayList<Integer>();
        for(int i=0;i<10;i++)
            list.add(i);
        for(int i=0;i<5;i++)
            list.add(i);
        System.out.println(list);
        listRemove(list);
        System.out.println(list);
    }

    private static void listRemove(ArrayList<Integer> list) {
        for(int i=0;i<list.size();i++){
            Integer j=list.get(i);
            if(j%2==0)
                list.remove(j);
        }
    }
}


这样也是正确的,只要不跟下标产生什么关系就ok。但是前提是for(int i=0;i<list.size();i++)这个循环而不是for each(Object o:list),因为删除一个是对的,但是删除多个那么就会报异常Exception in thread "main" java.util.ConcurrentModificationException






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值