Java中删除容器中元素的方法
Java中删除容器中元素的方法
在做实验时,由于是第一次上手Java,所以对于一些使用方法还是有些不熟悉的,今天就来介绍一下我遇到的一个问题,就是如何删除容器中的元素,我们都知道常见的方法就是使用自带的remove(),我之前也是一直这样使用的,直到有一次发生了“莫名其妙”其实是因为我对Java了解的太少 的bug,下面就来对常用的Set,List,Map来分别看一下
1. Set中删除元素
首先看一下最基本的remove()用法:
public class tryness {
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("AAA");
set.add("BBB");
set.add("CCC");
set.remove("AAA");
System.out.println(set);
}
}
运行结果:
[CCC, BBB]
可见如果我们知道我们要删除哪个元素,直接用remove是很方便的。
但是考虑一个问题,如果我们Set中存入的是一个Person类,那么我们要根据Person类的某一属性去进行筛选然后再Set中删除他,这时我们就需要遍历Set然后一个一个的对比,满足条件再删除,直接用remove()是否会出问题呢,下面来看一下:
Person类:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
测试代码:
public class tryness {
public static void main(String[] args) {
Set<Person> set = new HashSet<Person>();
set.add(new Person("A", 13));
set.add(new Person("B", 14));
set.add(new Person("C", 12));
for(Person i : set) {
if(i.getAge() == 13) {
set.remove(i);
}
}
for(Person i : set) {
System.out.println(i.getName() + " " + i.getAge());
}
}
}
运行结果:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(Unknown Source)
at java.util.HashMap$KeyIterator.next(Unknown Source)
at set.tryness.main(tryness.java:16)
可以看见是存在异常的,原因就是我们在一边遍历一边删除时会破坏了原来的迭代器,而遍历是靠这个迭代器遍历的,所以会出现异常,那么怎么解决呢,下面给出两种方法:
方法1: 在遍历时,把应该删除的元素记录下来,待遍历后再进行删除操作,如下:
public class tryness {
public static void main(String[] args) {
Set<Person> set = new HashSet<Person>();
set.add(new Person("A", 13));
set.add(new Person("B", 14));
set.add(new Person("C", 12));
Person temp = null;
for(Person i : set) {
if(i.getAge() == 13) {
temp = i;
}
}
set.remove(temp);
for(Person i : set) {
System.out.println(i.getName() + " " + i.getAge());
}
}
}
运行结果:
C 12
B 14
但是这种方法有一种缺陷,就是如果在这个Set中可能很多元素都是我想删除的,那么就要建立很多个temp,这显然不是一个好的处理方法,这时我们可以采用方法2
方法2: 利用迭代器删除,具体操作方法如下:
public class tryness {
public static void main(String[] args) {
Set<Person> set = new HashSet<Person>();
set.add(new Person("A", 13));
set.add(new Person("B", 14));
set.add(new Person("C", 12));
Iterator<Person> it = set.iterator(); //获取set的迭代器
for(int i = 0; i < set.size(); i ++) {
Person temp = it.next(); //用temp来记录获取到的下一个元素
if(temp.getAge() == 13) {
it.remove(); //利用迭代器进行删除
i --; //此时set的size也减少了1,所以i应该不变,但是此次循环后i会++,所以现在这里--来抵消
}
}
for(Person i : set) {
System.out.println(i.getName() + " " + i.getAge());
}
}
}
运行结果:
C 12
B 14
2. List中删除元素
List中删除元素和Set中的一样,这里直接给出代码来对比,不再重复说明:
直接remove():
public class tryness {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("AAA");
list.add("BBB");
list.add("CCC");
list.remove("BBB");
System.out.println(list);
}
}
运行结果:
[AAA, CCC]
用迭代器删除:
public class tryness {
public static void main(String[] args) {
List<Person> list = new ArrayList<Person>();
list.add(new Person("A", 13));
list.add(new Person("B", 14));
list.add(new Person("C", 12));
Iterator<Person> it = list.iterator(); //获取set的迭代器
for(int i = 0; i < list.size(); i ++) {
Person temp = it.next(); //用temp来记录获取到的下一个元素
if(temp.getAge() == 13) {
it.remove(); //利用迭代器进行删除
i --; //此时set的size也减少了1,所以i应该不变,但是此次循环后i会++,所以现在这里--来抵消
}
}
for(int i = 0; i < list.size(); i ++) {
System.out.println(list.get(i).getName() + " " + list.get(i).getAge());
}
}
}
运行结果:
B 14
C 12
3. Map中删除元素
对于Map中删除元素,直接remove的不再做解释了,和前面一样,更重要的是用迭代器删除,这也是我更偏向的一种删除方式,因为对于Map中我们经常都是一边遍历一边删除的,因为可能有多个key对应同一个value,所以针对value删除是常有的情况,下面就来展示一下如何对想要的value进行删除:
public class tryness {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("AAA", 14);
map.put("BBB", 13);
map.put("CCC", 12);
map.put("DDD", 13);
Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator();
//对value为13的进行删除
for(int i = 0; i < map.size(); i ++) {
Map.Entry<String, Integer> temp = it.next();
if(temp.getValue().equals(13)) {
it.remove();
i --;
}
}
System.out.println(map);
}
}
运行结果:
{AAA=14, CCC=12}
4. 总结
有很多情况下我们是需要一边遍历一边删除的,虽然remove()方法是简单方便的,但是此时并不适用,而利用迭代器进行删除恰好完美的解决了这个问题,所以适用迭代器删除是一个很不错的方法,希望初学者可以尽快掌握这个方法,避免在remove()使用不当时出现bug。
此篇文章只是我个人理解,如果有错误欢迎指出,感谢阅读!