天天看点

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

实体类(User):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):import java.util.ArrayList;

import java.util.List;

public class UserList {

private List subList;

private List allList;

public UserList(){

subList=new ArrayList();

allList=new ArrayList();

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方法有问题?

原因解析,先看APIboolean removeAll(Collection> c)

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

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

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

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

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

具体代码为: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;

}public boolean remove(Object o) {

Iterator 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方法,其默认的仍是比较对象,所以会出现上述问题!

问题综述完毕,这个问题实质上很简单,只希望给遇到有同样疑问的朋友一点帮助。