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

简介: JavaSE——集合框架一(7/7)-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



目录
相关文章
|
28天前
|
存储 Java 数据处理
Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。
【10月更文挑战第16天】Java Set:无序之美,不重复之魅!Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。通过 hashCode() 和 equals() 方法实现唯一性,适用于需要唯一性约束的数据处理。示例代码展示了如何使用 HashSet 添加和遍历元素,体现了 Set 的高效性和简洁性。
27 4
|
30天前
|
Java
Java Set 是一个不包含重复元素的集合接口,确保每个元素在集合中都是唯一的
【10月更文挑战第14天】Java Set 是一个不包含重复元素的集合接口,确保每个元素在集合中都是唯一的。本文介绍了 Set 的独特特性和两个常用实现类:基于哈希表的 HashSet 和基于红黑树的 TreeSet。通过示例代码展示了它们如何高效地处理唯一性约束的数据。
44 3
|
5月前
|
存储 Java 索引
JavaSE——集合框架一(5/7)-Set系列集合:Set集合的特点、底层原理、哈希表、去重复原理
JavaSE——集合框架一(5/7)-Set系列集合:Set集合的特点、底层原理、哈希表、去重复原理
50 1
|
5月前
|
Java 索引
JavaSE——集合框架一(3/7)-List系列集合:特点、方法、遍历方式、ArrayList集合的底层原理
JavaSE——集合框架一(3/7)-List系列集合:特点、方法、遍历方式、ArrayList集合的底层原理
44 2
|
5月前
|
Java
JavaSE——集合框架二(6/6)-(案例)补充知识:集合的嵌套(需求与分析、问题解决、运行测试)
JavaSE——集合框架二(6/6)-(案例)补充知识:集合的嵌套(需求与分析、问题解决、运行测试)
77 0
|
6月前
|
Java
Java【代码分享 12】判断一个集合是否包含另一个集合中的一个或多个元素 retainAll() 及其他方法
Java【代码分享 12】判断一个集合是否包含另一个集合中的一个或多个元素 retainAll() 及其他方法
274 0
|
Java
Java Map集合的几种遍历方式与性能对比(包含lambda表达式)
综上所述:第三种遍历方式在数据量非常小时是最好的,第五种遍历方式是最简单粗暴的。
400 0
Java Map集合的几种遍历方式与性能对比(包含lambda表达式)
|
存储 算法 前端开发
嵌套遍历同一个数组的时候,试试Map优化
嵌套遍历同一个数组的时候,试试Map优化
147 0
集合线程安全问题:第一章:集合类不安全之并发修改异常
集合线程安全问题:第一章:集合类不安全之并发修改异常
126 0
集合线程安全问题:第一章:集合类不安全之并发修改异常
Java集合相关学习——如何实现List集合的去重操作?
Java集合相关学习——如何实现List集合的去重操作?
Java集合相关学习——如何实现List集合的去重操作?