java ArrayList removeAll() 不删除对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35960300/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ArrayList removeAll() not removing objects
提问by Sauron
I have the simple ArrayLists of the member class:
我有成员类的简单 ArrayLists:
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:
朋友的 ArrayList 包含所有用户朋友。我只想做的是从朋友列表中删除,如果有群组成员:
mFriends.removeAll(mGroupMembers);
Yet it does nothing to the mFriends
list...
然而它对mFriends
列表没有任何作用......
Looking at the log statements, the friend does in fact appear within the mGroupMember
list.
查看日志语句,朋友确实出现在mGroupMember
列表中。
Why doesn't this work?
为什么这不起作用?
回答by Kevin DiTraglia
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:
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());
}
}
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
.
此外,当您覆盖时.equals
,建议也覆盖,hashCode
以便对象在散列函数(如Set
或 )中也能正常工作Map
。
回答by Yassin Hajaj
You have to know that
你必须知道
ArrayList#removeAll(Collection)
ArrayList#removeAll(Collection)
makes a call to
打电话给
ArrayList#contains(Object)
ArrayList#contains(Object)
which makes a call to
调用
ArrayList#indexOf(Object)
ArrayList#indexOf(Object)
which finally calls
最后调用
Object#equals
Object#equals
So if equals
is not correctly overridden (following the equals
contract rules), you're not getting the correct behaviour.
因此,如果equals
没有正确覆盖(遵循equals
合同规则),您将无法获得正确的行为。
回答by Michael
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).
正如评论中所提到的,ArrayList
只有当它们的equals()
方法返回 true 时,才会删除 中的元素。非覆盖方法基于引用检查相等性(即它们必须是内存中的同一对象)。
What you probably want is to override equals
to be based on the properties of Member
, such as in the example below:
您可能想要的是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);
}
}
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.
此外,您应该在覆盖hashCode()
时覆盖,equals()
以便当两个对象相等时,它们具有相同的哈希码。hashCode 的非覆盖实现也基于引用相等。