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



目录
相关文章
|
2月前
|
存储 Java 数据处理
Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。
【10月更文挑战第16天】Java Set:无序之美,不重复之魅!Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。通过 hashCode() 和 equals() 方法实现唯一性,适用于需要唯一性约束的数据处理。示例代码展示了如何使用 HashSet 添加和遍历元素,体现了 Set 的高效性和简洁性。
45 4
|
6月前
|
存储 Java 索引
JavaSE——集合框架一(5/7)-Set系列集合:Set集合的特点、底层原理、哈希表、去重复原理
JavaSE——集合框架一(5/7)-Set系列集合:Set集合的特点、底层原理、哈希表、去重复原理
56 1
|
6月前
|
Java 索引
JavaSE——集合框架一(3/7)-List系列集合:特点、方法、遍历方式、ArrayList集合的底层原理
JavaSE——集合框架一(3/7)-List系列集合:特点、方法、遍历方式、ArrayList集合的底层原理
48 2
|
6月前
|
存储 Java
JavaSE——集合框架一(2/7)-Collection集合的遍历方式-迭代器、增强for循环、Lambda、案例
JavaSE——集合框架一(2/7)-Collection集合的遍历方式-迭代器、增强for循环、Lambda、案例
51 1
|
6月前
|
Java
JavaSE——集合框架二(6/6)-(案例)补充知识:集合的嵌套(需求与分析、问题解决、运行测试)
JavaSE——集合框架二(6/6)-(案例)补充知识:集合的嵌套(需求与分析、问题解决、运行测试)
78 0
|
6月前
|
Java
JavaSE——集合框架一(4/7)-List系列集合:LinkedList集合的底层原理、特有方法、队列、栈
JavaSE——集合框架一(4/7)-List系列集合:LinkedList集合的底层原理、特有方法、队列、栈
51 0
|
7月前
|
Java
Java【代码分享 12】判断一个集合是否包含另一个集合中的一个或多个元素 retainAll() 及其他方法
Java【代码分享 12】判断一个集合是否包含另一个集合中的一个或多个元素 retainAll() 及其他方法
317 0
|
Java
Java Map集合的几种遍历方式与性能对比(包含lambda表达式)
综上所述:第三种遍历方式在数据量非常小时是最好的,第五种遍历方式是最简单粗暴的。
417 0
Java Map集合的几种遍历方式与性能对比(包含lambda表达式)
|
存储 算法 前端开发
嵌套遍历同一个数组的时候,试试Map优化
嵌套遍历同一个数组的时候,试试Map优化
158 0
你还在遍历搜索集合?别逗了!Java 8 一行代码搞定,是真的优雅
背景 是的,如果你想搜索 List 集合,在 Java 8 之前可以使用自身的 contains/ indexOf 方法来查找元素,但仅限是完整元素,而不能模糊搜索或者自定义搜索,这时候确实只能遍历。 但现在都 2021 年了,你还在使用传统的遍历集合的方式搜索 List 集合元素吗? 那你就太 out 了,使用 Java 8 中的 Stream 搜索元素,一行代码即可搞定,而且还真的很优雅!这篇不会介绍 Stream 基础,Stream 系列我之前写过一个专题了,不懂的关注公众号Java技术栈,然后在公众号 Java 教程菜单中阅读。

热门文章

最新文章