Java 如何从列表中删除重复项

Java 如何从列表中删除重复项,java,android,Java,Android,我在一个联系人应用程序中工作,我必须列出联系人数据库中的所有联系人,但其中包含重复的联系人 例如,联系人号码(98*******33、+9198*******33)列为重复项 我使用了Set,在添加之前检查了我的列表是否包含电话号码,但这些都不起作用 ContactVO是Pojo类,contactVoList是我正在添加联系人的列表。 Cursor phones = getContext().getContentResolver().query(ContactsContract.Commo

我在一个联系人应用程序中工作,我必须列出联系人数据库中的所有联系人,但其中包含重复的联系人

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

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

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

修改
等于
,如下所示

 @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;
}
在ContactVO类中重写equals和hashCode方法可能有效

当您使用HashSet时,它会调用class的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();
}

试试这个…

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

建议的解决方案的问题在于,它们假设您的“副本”实际上是相等的字符串,而实际上它们不是

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

因此,在将所有电话号码添加到您的通话集中之前,您需要做的是将电话号码规范化为通用的标准格式。你必须自己决定那应该是什么样子。我建议您使用第二个示例:+不带空格或破折号。如果某个号码缺少国家/地区前缀,则您必须假定某个默认值,或者您可以从联系人提供的其他信息中获取该前缀


在此标准化之后,您的第一个数字也将是“+9198**********33”,并且“设置解决方案”将按预期工作。

您已经在使用
Set
这是解决方案。查看Set的自定义对象实现。@ADM是的,但重复项也不会被删除。这是因为您使用的是自定义类。您有重写
对象
方法。看看上面的解决方案。@ADM,我已经编辑了我的问题并添加了pojo类。你能检查一下吗。我已经跳过了equals()和hashcode()方法。您的
equals
方法包含几个错误。例如,将字符串与
=
进行比较,而不是将
进行比较;如果另一个对象属于不相关的类,则返回
true
;似乎返回值通常是它应该是什么的否定,…这应该起作用。我自己测试过了。请看更新的答案。一点也不。这不起作用。使用&。如何?因为我对java和android非常陌生,我尝试了上面的方法,但没有成功。谢谢你的时间帮助我。你能帮我改变equals方法来消除+91个重复项吗请看更新答案。这就是我现在所能建议的。我在blanksky有+91个副本。我在问题中提到过bro@KarthikKPN对不起,我在编辑答案时错过了。谢谢你的回答。但仍然存在+91个副本!
    @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;
    }