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

 我来答
就烦条0o
2016-05-27 · 知道合伙人软件行家
就烦条0o
知道合伙人软件行家
采纳数:33315 获赞数:46487
从事多年系统运维,喜欢编写各种小程序和脚本。

向TA提问 私信TA
展开全部
看到这个标题,估计很多人会纳闷:连集合类的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方法,不这样说不定哪天就会出问题。
千锋教育
2016-05-27 · 做真实的自己 用良心做教育
千锋教育
千锋教育专注HTML5大前端、JavaEE、Python、人工智能、UI&UE、云计算、全栈软件测试、大数据、物联网+嵌入式、Unity游戏开发、网络安全、互联网营销、Go语言等培训教育。
向TA提问
展开全部
List<String> list = new ArrayList<String>(); List<String> listAll = new ArrayList<String>(); list.add("jack"); list.add("tom"); listAll.addAll(list); listAll.add("zhuzhu"); System.out.println(listAll.size()); listAll.removeAll(list); System.out.println(listAll.size());
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式