Reputation: 6657
I have the simple ArrayLists of the member class:
ArrayList<Member> mGroupMembers = new ArrayList<>();
ArrayList<Member> mFriends = new ArrayList<>();
Member class:
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;
}
}
The ArrayList for friends contains all the users friends. What I simply wish to do is remove from the friends list, group members if present with:
mFriends.removeAll(mGroupMembers);
Yet it does nothing to the mFriends
list...
Looking at the log statements, the friend does in fact appear within the mGroupMember
list.
Why doesn't this work?
Upvotes: 14
Views: 27743
Reputation: 21995
You have to understand the sequence of invocation underneath it
-> ArrayList#removeAll(Collection)
|
| calls
|
|--> ArrayList#contains(Object)
|
| calls
|
|--> ArrayList#indexOf(Object)
|
| calls
|
|--> Object#equals
So if equals
is not correctly overridden (following the equals
contract rules), you're not getting the correct behaviour.
Upvotes: 10
Reputation: 1091
As mentioned in the comments, elements from the ArrayList
will only be removed if their equals()
method returns true. The non-overridden method checks for equality based on reference (i.e. they must be the same object in memory).
What you probably want is to override equals
to be based on the properties of Member
, such as in the example below:
@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);
}
}
In addition, you should override hashCode()
when overriding equals()
so that when two objects are equal, they have the same hash code. The non-overriden implementation of hashCode is also based on equality by reference.
Upvotes: 2
Reputation: 26078
How are 2 members determined to be equal? I'm guessing if they have the same ID, you deem them equal, however java wants them to be the exact same reference in memory which may not be the case. To correct for this you can override the equals
function to have it return if the ids are equal:
public class Member {
//..
@Override
public boolean equals(Object anObject) {
if (!(anObject instanceof Member)) {
return false;
}
Member otherMember = (Member)anObject;
return otherMember.getUserUID().equals(getUserUID());
}
}
Also when you override .equals
it is recommended to also override hashCode
so that the objects also work correctly in hashing functions like Set
or Map
.
Upvotes: 31