java 从 Android 中的 ArrayList 中删除重复的对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6715933/
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-10-30 16:59:35  来源:igfitidea点击:

Remove duplicate objects from a ArrayList in Android

javaandroidarraylisthashcodetreeset

提问by Alin

I know this has be discussed over and over again here, but none of the examples I've tried worked for me.

我知道这里已经反复讨论了这一点,但是我尝试过的示例都没有对我有用。

What I've got

我有什么

I access the Call log from Android and I get a list of all calls made. Of course, here I get a lot of duplicates. First I make a List

我从 Android 访问通话记录,并获得所有通话的列表。当然,在这里我得到了很多重复。首先我列一个清单

List<ContactObject> lstContacts = new ArrayList<ContactObject>();

Then I add objects into it

然后我将对象添加到其中

While (get some record in call log)
{
    ContactObject contact = new ContactObject();
    contact.SetAllProperties(......)  
    lstContacts.add(contact);  
}

Set<ContactObject> unique = new LinkedHashSet<ContactObject>(lstContacts);
lstContacts = new ArrayList<ContactObject>(unique);

The Contact Object class is simple

Contact Object 类很简单

public class ContactObject {

    public ContactObject() {
        super();
    }

 @Override
 public boolean equals(Object obj) {
     if (!(obj instanceof ContactObject))
        return false;

     return this.lstPhones == ((ContactObject) obj).getLstPhones(); 
 }

 @Override
 public int hashCode() {
     return lstPhones.hashCode();
 }

    private long Id;
    private String name;
    private List<String> lstPhones;  
    private String details;

   //... getters and settres
}

What I need

我需要的

I need to have a Contact only once in the list. As I've read around here there are a couple of things that can be done like Set, HashSet, TreeSet. TreeSet seems the best as it keeps the order just as I receive it from the Call log. I've tried to make my code work with it but no success. Could anyone be so kind to give me a sample code based on my example. Thank you for your time.

我只需要在列表中有一个联系人。正如我在这里读到的,有一些事情可以做,比如 Set、HashSet、TreeSet。TreeSet 似乎是最好的,因为它保持了我从通话记录中收到的顺序。我试图让我的代码使用它,但没有成功。任何人都可以根据我的示例给我一个示例代码。感谢您的时间。

The Working Solution.Thank you all for your support, you've made my day.

工作解决方案。谢谢大家的支持,你们让我开心了一天。

In ContactObject override the two methods

在 ContactObject 中覆盖两个方法

 @Override
     public boolean equals(Object obj) {
         if (!(obj instanceof ContactObject))
            return false;

         return lstPhones.equals(((ContactObject) obj).getLstPhones());
     }

     @Override
     public int hashCode() {
         return (lstPhones == null) ? 0 : lstPhones.hashCode();
     }

//Getters and Setters and COnstructor....

//Getter 和 Setter 以及构造函数....

Simply use it as

只需将其用作

Set<ContactObject> unique = new LinkedHashSet<ContactObject>(lstContacts);
lstContacts = new ArrayList<ContactObject>(unique);

采纳答案by u290629

LinkedHashSetwhich keeps insertion-order can be used in your case.

可以在您的情况下使用保持插入顺序的LinkedHashSet

HashSet: no order.

HashSet:无序。

TreeSet: sorted set, but not keep insertion order.

TreeSet:排序集,但不保持插入顺序。

EDIT: As Software Monkey commented, hashCode()and equals()should be overwritten in ContactObjectto fit the hash-based Set.

编辑:由于软件猴评论,hashCode()equals()应覆盖在ContactObject适合基于散列的集合。

回答by Muhammad Adil

Remove duplication of Custom Object

删除重复的自定义对象

Example of Removing duplicate using Comparator

使用 Comparator 删除重复项的示例

Lets suppose you have a class "Contact"

假设您有一个“联系人”

public class Contact implements Comparable<Contact> {


public String getName() {
    return this.Name;
}

public void setName(String name) {
    this.Name = name;
}

public String getNumber() {
    return this.Number;
}

public void setNumber(String number) {
    this.Number = number;
}


 ///// this method is very important you must have to implement it.
@Override
public String toString() {
    return "\n" +"Name=" + name + "   Number=" + Number;
}

Here is how you can remove duplicate entries using Set, just pass your list in the function and it will work for you. New list will be returned which will have no duplicated contacts.

这是使用Set删除重复条目的方法,只需在函数中传递您的列表,它就会为您工作。将返回没有重复联系人的新列表。

 public ArrayList<Contact>  removeDuplicates(ArrayList<Contact> list){
    Set<Contact> set = new TreeSet(new Comparator<Contact>() {

        @Override
        public int compare(Contact o1, Contact o2) {
            if(o1.getNumber().equalsIgnoreCase(o2.getNumber())){
                return 0;
            }
            return 1;
        }
    });
    set.addAll(list);

    final ArrayList newList = new ArrayList(set);
    return newList;
}

It worked for me so please try and give me your feedback. Thanks

它对我有用,所以请尝试给我您的反馈。谢谢

P.S: Credit goes to Nilanchala at this article

PS:本文归功于 Nilanchala

回答by vsm

For sure you can use TreeSet to store only once but a common mistake is do not override hashCode() and equal() methods:

当然你可以使用 TreeSet 只存储一次,但一个常见的错误是不要覆盖 hashCode() 和 equal() 方法:

This can fit for you:

这可能适合您:

 public boolean equals(Object obj) {
     if (!(obj instanceof ContactObject))
        return false;

     return this.id == ((ContactObject) obj).getId(); // you need to refine this
 }

 public int hashCode() {
     return name.hashCode();
 }

回答by sbridges

List<ContactObject> listContacts = new ArrayList<ContactObject>();
//populate...

//LinkedHashSet preserves the order of the original list
Set<ContactObject> unique = new LinkedHasgSet<ContactObject>(listContacts);
listContacts = new ArrayList<ContactOjbect>(unique);

回答by everton

Use Set's instead.

使用 Set 代替。

Set's works as an Mathematical collection, so it doesn't allow duplicated elements.

Set 是一个数学集合,所以它不允许重复的元素。

So it checks the equality and the .equals() methods for each element each time you add an new element to it.

因此,每次向其中添加新元素时,它都会检查每个元素的相等性和 .equals() 方法。