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
以便对象在散列函数(如Set
或Map
也能正常工作。
你必须知道这一点
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的非重写实现也基于引用相等。