解决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方法,这个记不清,可以自己研究一下

你可能感兴趣的:(list,String,filter,equals,iterator)