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

问题:两个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方法,这个记不清,可以自己研究一下
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值