代码:
List<DocListDto> docListDtos = docListDao.selectArchiveAll(typeID,null);List<DocListDto> docListDtosSmall = new ArrayList<DocListDto>();
DocListDto docListDto = null;
......
for (ArchiveListDto archiveListDto : archiveListDtos) {
docListDto = docListDao.selectArchiveDocListDto(archiveListDto.getTypeID(), archiveListDto.getDocId());
docListDtosSmall.add(docListDto);
}
boolean bl = docListDtos.removeAll(docListDtosSmall); //返回falseList都是ArrayList,docListDtosSmall是docListDtos的子集,我想从docListDtos中移除docListDtosSmall中的内容,但是使用removeAll方法不好用,
似乎只有两个集合的交集元素持有相同的引用时removeAll才起作用。有没有什么高效的办法让我做到这一点?

解决方案 »

  1.   

    要么在数据库直接SQL语句操作,SQL语句很强大的,
    或者用set,也很强大的
      

  2.   

    DocListDto是什么类型的?Object?
      

  3.   

    这个问题不是很难,我们仔细分析一下list及其子类ArrayList中调用的removeAll方法,发现其来自AbstractCollection类,其实现如下,
        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类,其实现如下:
        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了,写了个简单例子如下
    主类: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类,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方法,这个记不清,可以自己研究一下
      

  4.   

    先if contains判断存在另一个list里的元素,然后remove
      

  5.   

    谢谢各位弟兄的回复了。
    这个项目所有数据都是用xml文件保存的,底层实现的似乎不太理想,查询时只能附带简单的where条件。
    当时比较着急,用了个笨办法,先用主键作key把数据放到HashMap里:for (DocListDto dto : docListDtos) {
    docListDtosMap.put(dto.getDocId(), dto);
    }然后从map里移出符合条件的dto,最后把map里剩下的放进list里面:for (ArchiveListDto archiveListDto : archiveListDtos) {
    docListDto = docListDao.selectArchiveDocListDto(archiveListDto
    .getTypeID(), archiveListDto.getDocId());
    docListDtosMap.remove(docListDto.getDocId());
    }
    docListDtos.clear();
    docListDtos.addAll(docListDtosMap.values());
    不过就像各位说的,能用sql解决最好了,可是我们操作的是xml文件,底层操作不是我写的,只是听说用到了xpath和sax,我也不太懂,xml文件存放在两处:xindice数据库和直接放在文件系统中。对xml的查询能做到和传统sql语句一样吗?
      

  6.   

    XML底层这种操作没用过,帮不上忙了