ArrayList removeAll()不删除对象

我有成员类的简单ArrayLists:

ArrayList mGroupMembers = new ArrayList(); ArrayList mFriends = new ArrayList(); 

会员类:

 public class Member { private String userUID; private String userName; public String getUserUID() { return userUID; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public void setUserUID(String userUID) { this.userUID = userUID; } } 

用于朋友的ArrayList包含所有用户朋友。 我只想做的是从朋友列表中删除,如果有的话,小组成员:

 mFriends.removeAll(mGroupMembers); 

然而它对mFriends名单没有任何mFriends ……

查看日志语句,朋友确实出现在mGroupMember列表中。

为什么这不起作用?

如何确定2名成员是平等的? 我猜他们是否有相同的ID,你认为它们是相同的,但java希望它们在内存中是完全相同的引用,可能不是这种情况。 要纠正这个问题,你可以覆盖equals函数,让它在id相等时返回:

 public class Member { //.. @Override public boolean equals(Object anObject) { if (!(anObject instanceof Member)) { return false; } Member otherMember = (Member)anObject; return otherMember.getUserUID().equals(getUserUID()); } } 

此外,当您覆盖.equals ,建议还要覆盖hashCode以便对象在散列函数(如SetMap也能正常工作。

你必须知道这一点

ArrayList#removeAll(Collection)

打电话给

ArrayList#contains(Object)

打电话给

ArrayList#indexOf(Object)

最后打电话给

Object#equals


因此,如果未正确覆盖equals ( 遵循equals合约规则 ),则表示您没有获得正确的行为。

正如注释中所提到的,只有当equals()方法返回true时,才会删除ArrayList元素。 非重写方法基于引用检查相等性(即它们必须是内存中的相同对象)。

您可能想要的是将equals重写为基于Member的属性,例如下面的示例:

 @Override public void equals(Object o) { if(o == null) { return false; } else if (!(o instanceof Member)) { return false; } else { return ((Member) o).getUserUID.equals(this.userUID) && ((Member) o).getUserName.equals(this.userName); } } 

另外,在覆盖hashCode()时应该覆盖hashCode() ,这样当两个对象相等时,它们具有相同的哈希码。 hashCode的非重写实现也基于引用相等。