您的位置:首页 > 编程语言 > Java开发

如何使用Java List等集合类的removeAll方法

2016-09-29 11:45 330 查看
2014-05-10 21:40 7263人阅读 评论(2) 收藏 举报


 分类:

java学习(32) 


如何使用Java List等集合类的removeAll方法
http://blog.csdn.net/will_awoke/article/details/6528872
看到这个标题,估计很多人会纳闷:连集合类的removeAll方法都用不好还当什么程序员。

 

好吧,我承认我确实没用好这个方法,鄙视我吧。O(∩_∩)O哈!

 

先贴问题--->

 

实体类(User):

[java] view
plaincopy

public class User {  

      

    private String name;  

    private int age;  

      

    //setter and getter  

    public String getName() {  

        return name;  

    }  

    public void setName(String name) {  

        this.name = name;  

    }  

    public int getAge() {  

        return age;  

    }  

    public void setAge(int age) {  

        this.age = age;  

    }  

      

}  

 

测试集合类(UserList):

[java] view
plaincopy

import java.util.ArrayList;  

import java.util.List;  

  

public class UserList {  

      

    private List<User> subList;  

    private List<User> allList;  

      

    public UserList(){  

        subList=new ArrayList<User>();  

        allList=new ArrayList<User>();  

          

        for(int i=0;i<3;i++){  

            User user=new User();  

            user.setAge(i);  

            user.setName("lyh"+i);  

            subList.add(user);  

        }  

          

        for(int i=0;i<10;i++){  

            User user=new User();  

            user.setAge(i);  

            user.setName("lyh"+i);  

            allList.add(user);  

        }  

    }  

      

    public static void main(String[] args){  

        UserList userList=new UserList();  

        userList.allList.removeAll(userList.subList);//调用removeAll方法  

          

        System.out.println(userList.allList.size());  

          

    }  

}  

 

诸君认为最后的打印的结果是多少? 7 ?That's wrong !! 结果是10。

 

为什么会这样哪?难道removeAll方法有问题?

 

这个就是最近在用到removeAll时遇到的疑问(当然,我是把实际中的问题简单的抽象出来了)。当时百思不得其解,甚至幼稚的以为是Java的BUG 。殊不知是自己脑袋BUG了 !

 

 

原因解析:

 

先看API

[xhtml] view
plaincopy

boolean removeAll(Collection<?> c)  

  

从列表中移除指定 collection 中包含的其所有元素(可选操作)。   

没错,就是移除子集合包含的元素,那为什么不是7,而是10 。

再看API说明,移除所包含的其所有元素,注意这个字眼:包含!

 

因为在执行removeAll方法时,会先对集合元素进行比较,如果元素相等才执行移除操作,说到这,相信很多人都已经明白是怎么回事了,因为不相等(equals),所以没有执行移除。

 

查看源码进一步证实上述猜测,remove和removeAll的方法实现在:
java.util.AbstractCollection<E>


具体代码为:

[java] view
plaincopy





public boolean removeAll(Collection<?> c) {  

       boolean modified = false;  

       Iterator<?> it = iterator();  

       while (it.hasNext()) {  

           if (c.contains(it.next())) {  

               it.remove();  

               modified = true;  

           }  

       }  

       return modified;  

   }  

[java] view
plaincopy





public boolean remove(Object o) {  

        Iterator<E> it = iterator();  

        if (o==null) {  

            while (it.hasNext()) {  

                if (it.next()==null) {  

                    it.remove();  

                    return true;  

                }  

            }  

        } else {  

            while (it.hasNext()) {  

                if (o.equals(it.next())) {  

                    it.remove();  

                    return true;  

                }  

            }  

        }  

        return false;  

    }  

可以看到在调用removeAll方法时,实际上是循环调用了remove方法,而remove方法中有一段关键的代码:if (o.equals(it.next())) !

So,得出结论,因为上述例子中的实体类没有Override hashCode和equals方法 !而在执行removeAll方法时是通过equals方法来判断集合元素是否相等的,如果没有Override equals方法,其默认的仍是比较对象,所以会出现上述问题!

 

归根到底,还是基础没有掌握牢固,同时也给自己提了个醒,写实体类时尽量Override hashCode和equals方法,不这样说不定哪天就会出问题。

 

问题综述完毕,当然,这个问题实质上很简单,只希望给遇到有同样疑问的朋友一点帮助。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: