【问题标题】:How to remove duplicate from list [duplicate]如何从列表中删除重复项[重复]
【发布时间】:2018-01-07 06:53:22
【问题描述】:

我正在使用联系人应用程序,我必须列出联系人数据库中的所有联系人,但它包含重复项。

例如,联系人号码 (98*******33, +9198********33) 被列为重复号码。

我使用过设置,在添加之前检查了我的列表是否包含电话号码,但这些都不起作用!

ContactVO 是 Pojo 类,contactVoList 是我要添加联系人的列表。

   Cursor phones = getContext().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
            while (phones.moveToNext()) {
                name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)).replace(" ", "");
                imageUri = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
                System.out.println("Name and Phone number = " + name + phoneNumber + imageUri);

                if (contactVOList.size() == 0) {
                    contactVOList.add(new ContactVO(imageUri, name, phoneNumber, false));
                } else {
                    if (!contactVOList.contains(phoneNumber)) {
                        contactVOList.add(new ContactVO(imageUri, name, phoneNumber, false));
                    }
                }

                System.out.println("List size before removing duplicates =" + contactVOList.size());
            }

            Set<ContactVO> s = new HashSet<ContactVO>();
            s.addAll(contactVOList);
            contactVOList = new ArrayList<ContactVO>();
            contactVOList.addAll(s);

我的 Pojo 课

public class ContactVO {
    private String ContactImage;
    private String ContactName;
    private String ContactNumber;
    private int hashCode;
    String id;
    boolean clicked;

    public ContactVO(String id) {
        this.id = id;
    }

    public boolean isClicked() {
        return clicked;
    }

    public void setClicked(boolean clicked) {
        this.clicked = clicked;
    }

    public String getId() {


        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public ContactVO(String ContactImage, String ContactName, String ContactNumber, Boolean clicked) {
        this.ContactImage = ContactImage;
        this.ContactName = ContactName;
        this.ContactNumber = ContactNumber;
        this.clicked = clicked;
    }


    public String getContactImage() {
        return ContactImage;
    }

    public void setContactImage(String contactImage) {
        this.ContactImage = ContactImage;
    }

    public String getContactName() {
        return ContactName;
    }

    public void setContactName(String contactName) {
        ContactName = contactName;
    }

    public String getContactNumber() {
        return ContactNumber;
    }

    public void setContactNumber(String contactNumber) {
        ContactNumber = contactNumber;
    }

    @Override
    public boolean equals(Object obj) {
        // TODO Auto-generated method stubs
        if (obj instanceof ContactVO) {
            ContactVO temp = (ContactVO) obj;
            System.out.println("this.getctno" + this.getContactNumber());
            System.out.println("temp.getctno" + temp.getContactNumber());
            if (this.getContactNumber() == temp.getContactNumber() && this.getContactName() == temp.getContactName() && (this.getContactNumber()).contains(temp.getContactNumber()))
                return false;
        }
        return true;
    }

    @Override

    public int hashCode() {
        // TODO Auto-generated method stub
        return (this.getContactNumber().hashCode() + this.getContactName().hashCode());
    }
}

【问题讨论】:

  • 您已经在使用Set,这是解决方案。请查看 This thread 以了解 Set 的自定义对象实现。
  • @ADM 是的,但也不会删除重复项。
  • 那是因为您使用的是自定义类。你已经覆盖了Object 方法。看看上面的解决方案。
  • @ADM,我已经编辑了我的问题并添加了 pojo 类。请您检查一次。我已经覆盖了 equals() 和 hashcode() 方法。
  • 您的equals 方法包含多个错误。例如,您将字符串与== 而非equals 进行比较;如果另一个对象属于不相关的类,则返回true;似乎返回值通常是它应该是什么的否定,...

标签: java android


【解决方案1】:

在 ContactVO 类中重写 equalshashCode 方法可能会起作用。

当你使用HashSet时,它会调用类的hashCode方法来获取实例的hash码,然后HashSet会将hash码传递给一个索引,索引就是对象所在的位置。添加新对象时,它会获取一个索引并检查该位置是否有对象,如果没有,则添加该对象,否则将遍历链接列表并调用 equals 方法找到相同的对象,如果没有,该对象将被附加到链接列表中。

代码示例:

@Override
public boolean equals(Object obj) { 
    ContactVO tmpContact= (ContactVO) obj; 
    if (phoneNumber.equals(tmpContact.phoneNumber)) return true; 
    else return false; 
} 

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

【讨论】:

  • 我有 +91 个重复 @blanksky。我在我的问题中提到过兄弟
  • @KarthikKPN 对不起,我在编辑答案时想念它。
【解决方案2】:

试试这个...

    @Override
    public boolean equals(Object obj) {
        // TODO Auto-generated method stubs
        if (obj instanceof ContactVO) {
            ContactVO temp = (ContactVO) obj;
            System.out.println("this.getctno" + this.getContactNumber());
            System.out.println("temp.getctno" + temp.getContactNumber());
            if (this.getContactNumber().equals(temp.getContactNumber()) || this.getContactNumber().endsWith(temp.getContactNumber()) ||
            temp.getContactNumber().endsWith(this.getContactNumber()))
                return true;
        }
        return false;
    }

【讨论】:

  • 感谢您的回答。但是 +91 重复仍然存在!
【解决方案3】:

修改equals如下。

 @Override
public boolean equals(Object obj) {
    if (obj instanceof ContactVO) {
        ContactVO temp = (ContactVO) obj;
        System.out.println("this.getctno" + this.getContactNumber());
        System.out.println("temp.getctno" + temp.getContactNumber());
        if (this.getContactNumber().equals(temp.getContactNumber()) &&
                this.getContactName().equals( temp.getContactName()))
            return true;
    }
    return false;
}
@Override
public int hashCode() {
    // TODO Auto-generated method stub
    return (this.getContactNumber().hashCode() + this.getContactName().hashCode());
}

请记住,像“98*******33, +9198********33”这样的数字不是等于。 如果你想测试它们是否相等并返回true,那么你必须修改equals()。 它不是最终的解决方案。不过你可以试一试。

 @Override
public boolean equals(Object obj) {
    if (obj instanceof ContactVO) {
        ContactVO temp = (ContactVO) obj;
        if(getContactNumber().length()>=temp.getContactNumber().length()){
            if (this.getContactNumber().endsWith(temp.getContactNumber()) &&
                    this.getContactName().equals( temp.getContactName()))
                return true;
        }else{
            if (temp.getContactNumber().endsWith(this.getContactNumber()) &&
                    this.getContactName().equals( temp.getContactName()))
                return true;
        }
    }
    return false;
}

【讨论】:

  • 这应该可以。我自己测试过。请参阅更新的答案。
  • 一点也不。这行不通 .with && .How ?
  • 由于我对 java 和 android 很陌生,所以我尝试了上面的方法,但它没有用
  • 感谢您抽出宝贵时间帮助我。你能帮我看看如何改变equals方法来消除+91重复
  • 查看更新答案。这就是我现在所能建议的。谢谢
【解决方案4】:

建议的解决方案的问题是,他们认为您的“重复项”实际上是相等的字符串,但事实并非如此。

您有“98*******33”和“+9198********33”作为重复项,但它们不是相等的字符串。

因此,在将所有电话号码添加到您的集合之前,您需要做的是将电话号码规范化为通用的标准格式。你必须自己决定它应该是什么样子。我会建议像你的第二个例子:+ 没有任何空格或破折号。如果某个号码缺少国家/地区前缀,您将不得不假设一些默认值,或者您可以从联系人的其他信息中推导出它。

在此规范化之后,您的第一个数字也将是“+9198*******33”,并且“Set-Solution”将按预期工作。

【讨论】:

    猜你喜欢
    • 2019-12-07
    • 2014-09-30
    • 2011-10-09
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 2020-04-22
    • 1970-01-01
    相关资源
    最近更新 更多