欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ArrayList 一边遍历 一边删除指定对象 或删除整个类型 (删除方面)最全的

程序员文章站 2022-04-11 19:00:07
...

2020、6、13著

关于ArrayLiat 删除方面 相关知识 最全的 (听我们老师说 这是面试时的坑


用ArrayList,存放一些字符串
有英文的,有数字的
然后把数字的去除



"abc", "def","123","aaa","666","ddd","888","bye"
 


我们统一一下测试用例吧
经过处理,得到:"abc", "def","aaa","ddd","bye"
说明程序正确


list.add 有数字型 也有字符串型 但要求删除全部数字型:

最初的代码:

 

public class ArrayListTest {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();

list.add("def");
	list.add("123");
	list.add("aaa");
	list.add("666");
	list.add("123");
	list.add("ddd");
	list.add("888");
	list.add("bye");

	String str="[0-9]+";  //正则表达式 纯数字型
	Pattern pattern=Pattern.compile(str);
	
	for(int i=0;i<list.size();i++) {
		String str2=list.get(i);
		Matcher matcher=pattern.matcher(str2);
		if(matcher.matches()) {
			list.remove(i);
			i=i-1;   //最为关键的一部。
		}
		
	}
	
	String s=String.join("\",\"",list);
    System.out.println("\""+s+"\""	);}}

为什么说是 i=i-1 最为关键呢 同学们请看下面:

这里遍历用的是ArrayList实现的迭代器Iterator的hasNext()、next()方法,但是删除用的却是ArrayList的remove(Object o)方法。这样迭代器无法感知ArrayList中元素的变化,比如ArrayList中已经删了一个元素,后面的元素都向前移动一个位置,原本Iterator位置上的元素被删除了并且被后面的元素替代,而Iterator不知道,下一次迭代的时候就会以为这个元素已经被遍历过了而直接跳过。

如果没有 i=i-1; 后果是啥呢?

你会发现,你 add 多个数字型字符串 且 挨在一起 在删除过程中会少删除 至少少删除一个!

下面用 底层 iterator 迭代器实现:


public class ArrayListTest {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();
	list.add("def");
	list.add("123");
	list.add("aaa");
	list.add("666");
	list.add("123");
	list.add("ddd");
	list.add("888");
	list.add("bye");

	String str="[0-9]+";
	Pattern pattern=Pattern.compile(str);
	Iterator<String> iterator = list.iterator();
	while(iterator.hasNext()) {
		Matcher matcher=pattern.matcher(iterator.next());
		if(matcher.matches()) {  //是否完全匹配
			iterator.remove();
		}
		
	}
	
	String s=String.join("\",\"",list);
    System.out.println("\""+s+"\""	);

还有一种我同学发现的 Integer.parseInt()能否转化 来识别最终删除

ArrayList 一边遍历 一边删除指定对象 或删除整个类型 (删除方面)最全的

 


下面删除:

指定对象“666”:

ArrayList 一边遍历 一边删除指定对象 或删除整个类型 (删除方面)最全的

 

报错了 同学们 想想是为啥呢:

foreach循环在实际执行时,其实使用的是Iterator,使用的核心方法是hasnext()和next()。

和上面道理一样 使用迭代器就可解决:

public class ArrayListTest {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();

		list.add("def");
		list.add("123");
		list.add("aaa");
		list.add("666");
		list.add("123");
		list.add("ddd");
		list.add("888");
		list.add("bye");
	
		Iterator<String> iterator = list.iterator();
		while(iterator.hasNext()) {
		
			if(iterator.next().equals("666")) {  //是否完全匹配
				iterator.remove();
			}
		}
		String s=String.join("\",\"",list);
        System.out.println("\""+s+"\""	);
		}
	
}

看个我同学使用的新办法:list.removeIf();  只用一行代码删除目标 非常强大!

public class ArrayListTest {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();

		list.add("def");
		list.add("123");
		list.add("aaa");
		list.add("666");
		list.add("123");
		list.add("ddd");
		list.add("888");
		list.add("bye");
	
		list.removeIf(s -> s.equals("888")); //只用一行代码 这个就牛皮了
		
//		Iterator<String> iterator = list.iterator();
//		while(iterator.hasNext()) {
//		
//			if(iterator.next().equals("666")) {  //是否完全匹配
//				iterator.remove();
//			}
//		}
		String s=String.join("\",\"",list);
        System.out.println("\""+s+"\""	);
		}
	
}

list.removeIf() 相关链接:

https://blog.csdn.net/qq_33829547/article/details/80277956?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

面试的链接:

https://mp.weixin.qq.com/s?__biz=MzI1NDQ3MjQxNA==&mid=2247492109&idx=2&sn=6a6bd03006645302af5c7c5aa1461d91&chksm=e9c61bbcdeb192aaa98b62f3ccf1f2f6a59f4bab0d1a60c4b80b14f032c4311072cde5ebbe23&mpshare=1&scene=23&srcid=&sharer_sharetime=1592040747480&sharer_shareid=2c2dd7d0624b71e1960b5a7ab4c8042b#rd