JavaSE——集合框架一(7/7)-Collection集合的总结、集合的并发修改异常问题(案例引入、for循环-解决方法、迭代器-解决方法、小结)

目录

Collection集合的总结

集合的并发修改异常问题

案例引入

for循环-解决方法

迭代器-解决方法

小结


Collection集合的总结

1、如果希望记住元素的添加顺序,需要存储重复的元素,又要频繁的根据索引查询数据

  • 用ArrayList集合(有序、可重复、有索引),底层基于数组的。(常用)

2、如果希望记住元素的添加顺序,且增删首尾数据的情况较多

  • 用LinkedList集合(有序、可重复、有索引l),底层基于双链表实现的。

3、如果不在意元素顺序,也没有重复元素需要存储,只希望增删改查都快

  • 用HashSet集合(无序,不重复,无索引),底层基于哈希表实现的。(常用)

4、如果希望记住元素的添加顺序,也没有重复元素需要存储,且希望增删改查都快?

  • 用LinkedHashSet集合(有序,不重复,无索引),底层基于哈希表和双链表。

5、如果要对元素进行排序,也没有重复元素需要存储?且希望增删改查都快?

  • 用TreeSet集合,基于红黑树实现。

集合的并发修改异常问题

  • 使用迭代器遍历集合时,又同时在删除集合中的数据,程序就会出现并发修改异常的错误。

案例引入

通过一个小案例引入:

完成一个需求,找出集合中全部带“李”的名字,并从集合中删除。

使用迭代器实现

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

public class Test {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("王麻子");
        list.add("小李子");
        list.add("李爱花");
        list.add("张全蛋");
        list.add("晓李");
        list.add("李玉强");
        System.out.println(list);

        //需求:找出集合中全部带"李"的名字,并从集合中删除
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            String name = it.next();
            if(name.contains("李")){
                list.remove(name);
            }
        }
        System.out.println(list);
    }
}

运行结果:

使用for循环实现

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

public class Test {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("王麻子");
        list.add("小李子");
        list.add("李爱花");
        list.add("张全蛋");
        list.add("晓李");
        list.add("李玉强");
        System.out.println(list);

        //需求:找出集合中全部带"李"的名字,并从集合中删除
        for(int i = 0;i < list.size();i++){
            String name = list.get(i);
            if(name.contains("李")){
                list.remove(name);
            }
        }
        System.out.println(list);
    }
}

使用for循环来实现,每次遇到带“李” 的名字,删除之后索引++,会跳过一个元素的检查,极大概率导致漏删。

运行结果:

for循环-解决方法

每次检索到带“李”的名字,就把i再减一,使索引回到正确的位置;或者从后往前进行检索和删除。

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

public class Test {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("王麻子");
        list.add("小李子");
        list.add("李爱花");
        list.add("张全蛋");
        list.add("晓李");
        list.add("李玉强");
        System.out.println(list);

        //需求:找出集合中全部带"李"的名字,并从集合中删除
        for(int i = 0;i < list.size();i++){
            String name = list.get(i);
            if(name.contains("李")){
                list.remove(name);
                i--;
            }
        }
        //或者倒着进行删除
        System.out.println(list);
    }
}

运行结果:

迭代器-解决方法

迭代器的解决方法就比较直接,我们在删除的时候就使用迭代器自己的删除方法就可以了:

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

public class Test {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("王麻子");
        list.add("小李子");
        list.add("李爱花");
        list.add("张全蛋");
        list.add("晓李");
        list.add("李玉强");
        System.out.println(list);

        //需求:找出集合中全部带"李"的名字,并从集合中删除
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            String name = it.next();
            if(name.contains("李")){
                it.remove();  //删除迭代器当前遍历到的数据,每删除一个数据后,相当于也在底层做了i--
            }
        }
        System.out.println(list);
    }
}

运行结果也同样是:

注意:用增强for循环(foreach)遍历集合并删除数据,没有办法解决bug;同样,Lambda表达式也无法解决,因为其源代码也是使用foreach遍历的。

小结

  • 由于增强for循环遍历集合就是迭代器遍历集合的简化写法,因此,使用增强for循环遍历集合,又在同时删除集合中的数据时,程序也会出现并发修改异常的错误。

怎么保证遍历集合同时删除数据时不出bug?

  • 使用迭代器遍历集合,但用迭代器自己的删除方法删除数据即可
  • 如果能用for循环遍历时:可以倒着遍历并删除;或者从前往后遍历,但删除元素后做i--操作

END


学习自:黑马程序员——JavaSE课程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值