我有成员类的简单ArrayLists:
ArrayList<Member> mGroupMembers = new ArrayList<>();
ArrayList<Member> 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;
}
}
FriendsList for Friends包含所有用户朋友。我只想删除朋友列表,组成员如果出现:
mFriends.removeAll(mGroupMembers);
然而它对mFriends
列表......
查看日志语句,朋友确实出现在mGroupMember
列表中。
为什么这不起作用?
答案 0 :(得分:16)
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
等散列函数中也能正常工作。
答案 1 :(得分:5)
你必须知道
ArrayList#removeAll(Collection)
拨打
ArrayList#contains(Object)
调用
ArrayList#indexOf(Object)
最后调用
Object#equals
因此,如果未正确覆盖equals
(following the equals
contract rules),则表示您没有获得正确的行为。
答案 2 :(得分:1)
正如评论中所提到的,ArrayList
中的元素只有在equals()
方法返回true时才会被删除。非重写方法根据引用检查相等性(即它们必须是内存中的同一对象)。
您可能希望覆盖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()
时应覆盖equals()
,以便当两个对象相等时,它们具有相同的哈希码。 hashCode的非重写实现也基于引用相等。