解决collection调用removeAll()移除不了不同引用同值对象的问题

本文详细解析了Java中使用ArrayList的removeAll方法时遇到的问题,即当两个List中的对象值相同但引用不同时,如何正确地从一个集合中移除另一个集合中的元素。通过覆写equals方法解决了这一难题。

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

问题:两个List都是ArrayList, 其中一个list1是另一个list2的子集,我想从list2中移除list1中的内容,但是使用removeAll方法不好用, 似乎只有两个集合的交集元素持有相同的引用时removeAll才起作用,而list2和list1中是不同的引用,虽然值相同。
有没有什么高效的办法让我做到这一点?

解决方法:

这个问题不是很难,我们仔细分析一下list及其子类ArrayList中调用的removeAll方法,发现其来自AbstractCollection类,其实现如下,

Java code
public boolean retainAll(Collection<?> c) { boolean modified = false; Iterator<E> e = iterator(); while (e.hasNext()) { if (!c.contains(e.next())) { e.remove(); modified = true; } } return modified; }

我们可以看到,其中主要是通过contains方法来判断两个collection对象中内容之间的关系,根据上下文,我们知道这里contains的实现还是在AbstractCollection类,其实现如下:
Java code
public boolean contains(Object o) { Iterator<E> e = iterator(); if (o==null) { while (e.hasNext()) if (e.next()==null) return true; } else { while (e.hasNext()) if (o.equals(e.next())) return true; } return false; }

我们可以看到如果两个都不为空的时候,就主要看对象o的equals方法实现了,所以这里,我们只要覆写ArchiveListDto类的equals方法就OK了,写了个简单例子如下
主类:

Java code
package example5; import java.util.ArrayList; import java.util.List; public class HelpCsdnUser { /** * @param args */ public static void main(String[] args) { List l1 = new ArrayList(); l1.add(new SimpleBean("1")); l1.add(new SimpleBean("2")); l1.add(new SimpleBean("3")); List l2 = new ArrayList(); l2.add(new SimpleBean("1")); System.out.println("before filter:"); for (SimpleBean bean : (List<SimpleBean>)l1) { System.out.println(bean.getName()); } l1.removeAll(l2); System.out.println("after filter:"); for (SimpleBean bean : (List<SimpleBean>)l1) { System.out.println(bean.getName()); } } }


SimpleBean类,
Java code
package example5; public class SimpleBean{ private String name=null; private int age=0; public SimpleBean(String name) { this.name = name; } public String getName() { return name; } public void setName(String tempName) { name=tempName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public boolean equals(Object destination) { boolean retVal = false; if(destination != null && destination.getClass().equals(this.getClass())) { SimpleBean bean = (SimpleBean)destination; if(bean.getName()==null && this.getName()==null) { retVal = true; } else { if(bean.getName()!=null && bean.getName().equals(this.getName())) { retVal = true; } } } return retVal; } }

输出结果为:
before filter:
1
2
3
after filter:
2
3

不过从前记得在覆写equals方法时,最好同时覆写hashCode方法,这个记不清,可以自己研究一下
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值