删除List中元素的正确姿势

本文探讨了在Java中从List中安全删除元素的方法。通过对比错误和正确的实现方式,揭示了直接在循环中删除元素可能导致的并发修改异常问题,并提供了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通常需要把List中的某些元素进行删除,容易犯的错误就是直接做循环,然后if判断进行删除,这种往往会报错,因为列表大小以及指针同时改变了,之所以说往往,是因为删除某些元素时并不会报错。如下所示:

//main函数
public static void main(String[] args) {
        List<String> originList = new ArrayList<String>();
        for(int i = 0; i < 5; i++) {
            originList.add(i + "");
        }
        delete1(originList, "2");//错误的写法
        delete1(originList, "2");//正确的写法
        System.out.println(originList);
    }

    /**
     * 第一种写法,错误的写法,list在循环过程中删除自己的元素
     */
    private static void delete1(List<String> list, String string) {
        for(String str : list) {
            if(string.equals(str)) {
                list.remove(string);
            }
        }

    }

Exception in thread “main” java.util.ConcurrentModificationException
at
java.util.ArrayListItr.checkForComodification(ArrayList.java:901)atjava.util.ArrayListItr.next(ArrayList.java:851)
at testJava.TestDeleteEleInList.delete1(TestDeleteEleInList.java:21)
at testJava.TestDeleteEleInList.main(TestDeleteEleInList.java:13)
但是在例子中删除元素”3”时并不会报错,输出的是正确的结果,所以这个错误隐藏得有点深。
正确的写法应该为使用Iterator进行遍历

/**
     * 正确的写法
     */
    private static void delete2(List<String> originList, String string) {
        Iterator<String> iterator = originList.iterator();
        while (iterator.hasNext()) {
            String temp = iterator.next();
            if(string.equals(temp)) {
                iterator.remove();
            }
        }
    }
任务描述 本关任务:定义四种开发中常用的集合并添加数据。 相关知识 为了完成本关任务,你需要掌握: 1.集合的体系结构; 2.如何创建常见的集合。 在前两个关卡中我们学习的ArrayList集合只是集合的一个部分,Java中的集合可没那么简单呢,Java中的集合是一个大家族,接下来我们就来见识一下这个家族吧。 集合的体系结构 Java中的集合分为两大家族,一个是Collection家族,Collection家族有三大成员:List、Queue、Set,这三大成员有三个子类(实际还有很多,这里不一一列举)分别是,ArrayList,LinkedList,HashSet,这个家族有一个特点,那就是他们都是单身,集合中的元素都是独立存在的。 另一个就是Map家族了,这个家族的特点就是他们都是成双成对(key和value)一起出现的,让Collection家族很是羡慕啊^_^。 如何使用常见的集合 创建LinkedList集合,并添加数据 LinkedList list = new LinkedList(); list.add("hello"); 创建HashSet集合,并添加数据 HashSet set = new HashSet(); set.add("hello"); 创建HashMap集合,并添加数据 HashMap map = new HashMap(); map.put("name","张三"); 以上就是创建几个常用集合创建实例并添加数据的方式,可以看到我们使用的方式除了LinkedList之外都是父类的引用指向子类对象,相信你还不陌生,这个我们在学习多态这个知识点的时候讲过,这种方式可以大大的提高程序的可扩展性。 通过上述代码可以发现Map集合添加数据和Collection家族成员添加数据的方式不一样,Map集合添加数据必须有两个,即一个是Key一个是Value。 面试官 Duang Duang Duang面试官来啦,快坐好,摆好姿势。 好了,我要开始提问了: 问:Set集合与List集合有什么区别呢? 答:Set集合中的数据不可重复,数据是无序的,List集合的数据可以重复,数据是有序的。 问:就没啦?[严肃脸] 答:哦哦,还有,Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变,List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变。 问:Map集合中的元素可以重复吗? 答:不可以! 问:你说一说,LinkedListArrayList的区别吧。 答:好嘞,LinkedList集合增删速度更快,ArrayList改查更快。 问:咳咳咳,下一位! 答:诶诶诶,别呀,我还没说完呢: ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。LinkedList是双向链表。 对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 面试官:嗯,这次算你过关,等下次通知吧! 我:...... 编程要求 请仔细阅读右侧代码,根据方法内的提示,在Begin - End区域内进行代码补充,具体任务如下: 分别定义HashSet、ArrayList、LinkedList、HashMap集合。并向每一个集合中添加www.educoder.net,Map集合的key设置为address,最后将每一个集合返回。 测试说明 补充完代码后,点击测评,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。 测试输入:无 预期输出: www.educoder.net www.educoder.net www.educoder.net www.educoder.net package step3; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; public class HelloWorld { public HashSet getHashSet(){ /********** Begin **********/ /********** End **********/ } public ArrayList getArrayList(){ /********** Begin **********/ /********** End **********/ } public LinkedList getLinkedList(){ /********** Begin **********/ /********** End **********/ } public Map getHashMap(){ /********** Begin **********/ /********** End **********/ } }
03-18
<think>好的,我现在需要解决这个编程问题。题目要求我在四个不同的集合(HashSet、ArrayList、LinkedList、HashMap)中添加字符串"www.educoder.net",其中HashMap的键是"address",然后将这些集合返回。看起来每个方法对应一个集合类型,我需要分别实现每个方法。 首先,看第一个方法getHashSet。HashSet的创建应该是new HashSet<>(),然后调用add方法添加元素。记得返回这个HashSet。那代码应该是创建对象,添加元素,然后返回。 接下来是getArrayList方法,同样道理,new ArrayList<>(),然后add,返回ArrayList。 第三个是getLinkedList,这个直接用new LinkedList(),然后add,返回这个列表。 最后一个getHashMap,这里要注意,HashMap的键是"address",值是要添加的字符串。所以应该用put方法,参数是"address"和那个字符串。然后返回这个map。 但需要注意每个方法返回的类型是否正确。比如getHashMap返回的是Map接口,所以创建的时候可以用HashMap实例,然后返回。其他方法返回的都是具体的集合类型吗?比如getHashSet返回的是HashSet类型,而方法声明是public HashSet,所以没问题。 现在需要检查每个方法是否正确初始化,并添加了正确元素。例如,在HashMap中是否正确使用了put方法而不是add,因为Map的添加是用put的。 然后测试输出四个集合的内容。每个集合中的元素应该都包含那个字符串。对于HashMap来说,它的键是address,对应的值是字符串,所以当输出时可能只是获取值部分。但测试的预期输出显示四个相同的字符串,所以可能在测试代码中,每个集合被处理后提取出对应的元素。例如,HashMap的get("address")会返回这个值。 现在,我需要将每个方法中的代码补全。比如在getHashSet方法里: 创建HashSet对象,添加字符串,然后返回。类似: HashSet set = new HashSet(); set.add("www.educoder.net"); return set; 同理,ArrayList和LinkedList也是一样的添加方式。而HashMap则是: HashMap map = new HashMap(); map.put("address", "www.educoder.net"); return map; 但要注意,Java中的泛型是否需要指定?比如题目中的代码可能没有使用泛型,所以直接使用原始类型是可以的。比如题目给的示例代码中,创建HashSet的时候没有指定泛型参数,所以可能正确的写法就是省略泛型。例如: public HashSet getHashSet() { HashSet set = new HashSet(); set.add("www.educoder.net"); return set; } 其他方法类似处理。比如ArrayList的添加方式一样,LinkedList也是如此。而HashMap的put方法参数是key和value,这里key是字符串"address",value是目标字符串。 那现在我需要将这些代码分别填写到对应的Begin和End区域。确保每个方法内部创建对应的集合对象,添加正确元素,并返回该集合。 可能需要注意大小写或者拼写错误,例如HashMap的键是否是字符串,有没有拼写错误,比如是否写成"addres"或者其他。必须严格按照题目要求,键是"address"。 所以现在每个方法的代码应该是这样的: 对于getHashSet: HashSet set = new HashSet(); set.add("www.educoder.net"); return set; 对于getArrayListArrayList list = new ArrayList(); list.add("www.educoder.net"); return list; 对于getLinkedList: LinkedList list = new LinkedList(); list.add("www.educoder.net"); return list; 对于getHashMap: HashMap map = new HashMap(); map.put("address", "www.educoder.net"); return map; 这样每个方法都创建了对应的集合实例,并添加了所需的元素。然后返回该集合。测试时,每个集合中的元素应该都能正确输出那个字符串。比如对于HashMap,测试可能取出map.get("address")的值,所以需要确保键正确。 现在将这些代码补全到对应的位置,注意每个方法内的变量名是否正确,以及是否返回正确类型的集合。例如,getHashMap方法返回的是Map类型,但这里可以返回HashMap实例,因为HashMap实现了Map接口,所以是正确的。 总结步骤: 1. 每个方法创建对应的集合对象。 2. 向集合中添加指定的元素(对于HashMap则是键值对)。 3. 返回该集合。</think>要完成本关任务,我们需要分别创建四种Java集合(HashSet、ArrayList、LinkedList、HashMap),并向其中添加指定数据。以下是逐步实现方法: ### 步骤解析 1. **HashSet集合** - **特点**:无序、元素不可重复 - **创建方式**:`new HashSet()` - **添加数据**:`.add("www.educoder.net")` 2. **ArrayList集合** - **特点**:有序、可重复、动态数组 - **创建方式**:`new ArrayList()` - **添加数据**:`.add("www.educoder.net")` 3. **LinkedList集合** - **特点**:双向链表、插入删除高效 - **创建方式**:`new LinkedList()` - **添加数据**:`.add("www.educoder.net")` 4. **HashMap集合** - **特点**:键值对存储,键不可重复 - **创建方式**:`new HashMap()` - **添加数据**:`.put("address", "www.educoder.net")` ### 最终代码实现 ```java package step3; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; public class HelloWorld { public HashSet getHashSet(){ /********** Begin **********/ HashSet set = new HashSet(); set.add("www.educoder.net"); return set; /********** End **********/ } public ArrayList getArrayList(){ /********** Begin **********/ ArrayList list = new ArrayList(); list.add("www.educoder.net"); return list; /********** End **********/ } public LinkedList getLinkedList(){ /********** Begin **********/ LinkedList list = new LinkedList(); list.add("www.educoder.net"); return list; /********** End **********/ } public Map getHashMap(){ /********** Begin **********/ HashMap map = new HashMap(); map.put("address", "www.educoder.net"); return map; /********** End **********/ } } ``` ### 代码解释 - **HashSet**:通过`new HashSet()`创建实例,添加元素时使用`add()`方法。 - **ArrayList**:通过`new ArrayList()`创建动态数组,使用`add()`方法添加元素。 - **LinkedList**:通过`new LinkedList()`创建链表结构,同样使用`add()`方法添加元素。 - **HashMap**:通过`new HashMap()`创建键值对集合,使用`put(key, value)`方法添加数据,其中键为`"address"`,值为目标字符串。 每个方法均按照要求实例化对应的集合对象,添加指定数据后返回该集合。测试时,平台会验证各集合中是否包含正确的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值