有重复的联系人排序列表,为啥?

Posted

技术标签:

【中文标题】有重复的联系人排序列表,为啥?【英文标题】:Sorted list of contacts having duplicates ,why?有重复的联系人排序列表,为什么? 【发布时间】:2018-05-26 22:40:36 【问题描述】:

我已将我的电话联系人排序并列出到一个数组列表中,但是,我在列表中找到了许多相同联系人姓名的重复项。这是怎么发生的?如何避免这种情况?

这是我尝试过的,

  cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null,
                "(" + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + ") ASC");

  while (cursor.moveToNext()) 

        try 

            name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
            phonenumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            contact_names_list.add(name);
            phone_num_list.add(phonenumber);


         catch (Exception e) 
            e.printStackTrace();
        

谁能帮忙??

【问题讨论】:

你可以使用HASHSET 有什么例子吗? 联系人是否属于多个群组?例如,在 SIM 卡和 Google 通讯录中。 是的,一些联系人在一个组中,但不是所有联系人,这里我得到每个联系人姓名的重复超过 2 个。 【参考方案1】:

这里似乎没有人回答你的问题。

您看到重复联系人的原因是您查询的是电话而不是联系人

android 中有 3 个主表:

    Contacts table - 每个联系人有一个项目 RawContacts 表 - 每个联系人每个帐户(例如 Google、Outlook、Whatsapp 等)有一个项目 - 多个 RawContacts 链接到单个 Contact Data 表 - 每个详细信息有一个项目(姓名、电子邮件、电话、地址等) - 每个数据项链接到单个 RawContact,多个 Data 行链接到每个 RawContact

您正在查询CommonDataKinds.Phone.CONTENT_URI,它是Data 表的一部分,因此如果联系人拥有不止一部手机,和/或拥有来自多个来源(例如Google 和Whatsapp)的同一部手机,您'将不止一次使用相同的CONTACT_ID 获得相同的电话。

解决方案是,使用HashMap(而不是HashSet),其中键是CONTACT_ID,因此您可以为每个联系人显示多个电话:

String[] projection = new String[]  CommonDataKinds.Phone.CONTACT_ID, CommonDataKinds.Phone.DISPLAY_NAME, CommonDataKinds.Phone.NUMBER ;
Cursor cursor = getContentResolver().query(CommonDataKinds.Phone.CONTENT_URI, projection, null, null, null);

HashMap<Long, Contact> contacts = new HashMap<>();

while (cursor.moveToNext()) 
    long id = cursor.getLong(0);
    String name = cursor.getString(1);
    String phone = cursor.getString(2);

    Contact c = contacts.get(id);
    if (c == null) 
        // newly found contact, add to Map
        c = new Contact();
        c.name = name;
        contacts.put(id, c);
    

    // add phone to contact class
    c.phones.add(phone);

cursor.close();


// simple class to store multiple phones per contact
private class Contact 
    public String name;
    // use can use a HashSet here to avoid duplicate phones per contact
    public List<String> phones = new ArrayList<>(); 

如果您想按名称对 HashMap 进行排序:

List<Contact> values = new ArrayList<>(contacts.values());
Collections.sort(values, new Comparator<Contact> 
    public int compare(Contact a, Contact b) 
        return a.name.compareTo(b.name);
    
);

// iterate the sorted list, per contact:
for (Contact contact : values) 
    Log.i(TAG, "contact " + contact.name + ": ");
    // iterate the list of phones within each contact:
    for (String phone : contact.phones) 
        Log.i(TAG, "\t phone: " + phone);
    

【讨论】:

你做得很好,这个完美解决了我的问题。感谢支持 我怎样才能得到一个排序列表,我已经尝试过treemap但它没有正确排序 您可以从 HashMap 中获取值,作为 ArrayList,然后对该 ArrayList 进行排序,请参阅我的更新 hai 当我这样排序时,我怎样才能以正确的顺序获取每个联系人对应的电话号码? :你能帮帮我吗?【参考方案2】:

你可以试试HashSet

公共类 HashSet 扩展 AbstractSet 实现 Set, 可克隆、可序列化

重复值是不允许的。

代码结构

 HashSet<String> hashSET = new HashSet<String>();
        hashSET.add("AA");
        hashSET.add("BB");
        hashSET.add("CC");
        hashSET.add("AA"); // Adding duplicate elements

那么

Iterator<String> j = hashSET.iterator();
        while (j.hasNext())
            System.out.println(j.next()); // Will print "AA" once.
    

现在SORT你的Hashset值使用TreeSet

TreeSet 实现了 SortedSet 接口,因此不会出现重复值 允许。

 TreeSet<String> _treeSET= new TreeSet<String>(hashSET);

【讨论】:

谢谢,但你能解释一下这是怎么发生的吗?我的意思是重复值?? @Gibs 没有来自 SIM 和 MOBILE。 (还有 Google 联系人) @Gibs 解决了吗? 谢谢它的工作,但我失去了列表的排序顺序 好的,谢谢你,我会试试的,我接受你的回答,因为它解决了重复的问题。【参考方案3】:

您的联系人中可能有多个组,该组将是 WhatsApp、Google 等。转到您的联系人并搜索 拥有 WhatsApp 帐户的联系人。将显示具有不同

的复式输入

您应该使用或更改您的 ContactsBean ,在您的 Bean 使用 HashSet

注意:HashSet可以避免重复输入more

HashSet 只包含唯一元素,可以避免HashSet 相同的关键元素形式

示例

public class ContactBean 
    private HashSet<String> number = new HashSet<String>(); 

    public void setNumber(String number) 
        if (number == null)
            return; 
        this.number.add(number.trim()); 
    

    public HashSet<String> getNumber() 
        return this.number; 
    

简单示例

//Creating HashSet and adding elements  
  
  HashSet<String> hashSet=new HashSet<String>();  
  hashSet.add("Dhruv");  
  hashSet.add("Akash");  
  hashSet.add("Dhruv");   //Avoiding this entry   
  hashSet.add("Nirmal");  

 //Traversing elements  
 
  Iterator<String> itr = hashSet.iterator();  
  while(itr.hasNext())  
   System.out.println(itr.next());
 

【讨论】:

【参考方案4】:

您可以使用HashSet 来避免重复:-

HashSet<String> hset = 
               new HashSet<String>();

你可以在HashSet中添加ArrayList:-

hset.add(your_string);

将您的 ArrayList 转换为 HashSet :-

Set<String> set = new HashSet<String>(your_arraylist_object);

HashSet避免重复输入:)

【讨论】:

谢谢你的回答,但我的问题是排序时如何避免重复,有什么帮助吗? 排序后将你的arraylist转换成hashset :) 检查从arraylist中删除重复的更新答案:)【参考方案5】:

我不知道你为什么从联系人那里得到重复的项目,也许电话联系人已经有重复的值。你可以在联系人应用程序中检查。 您应该始终在要避免重复项的任何地方使用集合数据结构。你可以找到更好的解释和例子here。

【讨论】:

【参考方案6】:

我认为您的重复是因为 Whatsapp 联系人干扰了联系人。所以你可以使用这样的东西

                      String lastPhoneName = "";
                     String lastPhoneNumber = "";

                    //IN YOUR CONTACT FETCHING WHILE LOOP , INSIDE TRY 
                   String contactName = c.getString(c
                                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                    String phNumber = c
                            .getString(c
                                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

                    if (!contactName.equalsIgnoreCase(lastPhoneName) && !phNumber.equalsIgnoreCase(lastPhoneNumber)) 

                        lastPhoneName = contactName;
                        lastPhoneNumber = phNumber;

                        ContactModel model = new ContactModel();
                        model.setContact_id(contactid);
                        model.setContact_name(contactName.replaceAll("\\s+", ""));
                        model.setContact_number(phNumber.replaceAll("\\D+", ""));


                        list_contact_model.add(model);

                     

这将检查以前的号码是否与旧号码相同而不是跳过它。我希望你得到你的答案

【讨论】:

【参考方案7】:

HashSet 在键/值对中添加项,并从项集中删除重复项。

List<String> phone_num_list= new ArrayList<>();
// add elements to phone_num_list, including duplicates
Set<String> hs = new HashSet<>();
hs.addAll(phone_num_list);
phone_num_list.clear();
phone_num_list.addAll(hs);

编码愉快!!

【讨论】:

以上是关于有重复的联系人排序列表,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何对实例类列表进行排序取决于其在飞镖或颤振中的属性[重复]

如何删除列表视图中重复的联系人?

使用 Baseadapter 时列表视图中的联系人图像重复

联系人列表字母排序索引

Phonegap:联系人列表排序

为啥我的数组列表只更改一个元素中的数据?