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。

此篇文章只是我个人理解,如果有错误欢迎指出,感谢阅读!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值