9

我知道这已经在这里讨论了一遍又一遍,但我尝试过的例子都没有为我工作。

我有什么

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

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

然后我将对象添加到其中

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);

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
}

我需要的

我只需要在列表中有一个联系人。正如我在这里所读到的,有几件事可以完成,例如 Set、HashSet、TreeSet。TreeSet 似乎是最好的,因为它保持了我从呼叫日志中收到的顺序。我试图让我的代码使用它,但没有成功。谁能根据我的例子给我一个示例代码。感谢您的时间。

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

在 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();
     }

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

只需将其用作

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

5 回答 5

8

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

HashSet:无序。

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

编辑:正如 Software Monkey 评论的那样,hashCode()应该equals()被覆盖ContactObject以适应基于哈希的集合。

于 2011-07-16T07:09:11.127 回答
7

删除自定义对象的重复

使用比较器删除重复项的示例

假设您有一个“联系”类

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;
}

这是使用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;
}

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

PS:本文归功于 Nilanchala

于 2016-10-25T14:13:01.577 回答
3

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

这可以适合您:

 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();
 }
于 2011-07-16T07:14:46.483 回答
2
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);
于 2011-07-16T07:09:27.897 回答
1

改用 Set 的。

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

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

于 2011-07-18T12:48:08.423 回答