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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 00:48:20  来源:igfitidea点击:

ArrayList removeAll() not removing objects

javaandroidarraylist

提问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 mFriendslist...

然而它对mFriends列表没有任何作用......

Looking at the log statements, the friend does in fact appear within the mGroupMemberlist.

查看日志语句,朋友确实出现在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 equalsfunction 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 .equalsit is recommended to also override hashCodeso that the objects also work correctly in hashing functions like Setor 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 equalsis not correctly overridden (following the equalscontract rules), you're not getting the correct behaviour.

因此,如果equals没有正确覆盖(遵循equals合同规则),您将无法获得正确的行为。

回答by Michael

As mentioned in the comments, elements from the ArrayListwill 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 equalsto 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 的非覆盖实现也基于引用相等。