代码之家  ›  专栏  ›  技术社区  ›  Jack

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

  •  5
  • Jack  · 技术社区  · 7 年前

    我已经在arraylist中整理并列出了我的电话联系人,但列表中有许多相同联系人的重复姓名。这是怎么发生的?如何避免这种情况?

    这就是我尝试过的,

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

    有人能帮忙吗??

    7 回复  |  直到 7 年前
        1
  •  6
  •   marmor    7 年前

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

    您看到重复联系人的原因是您正在查询 电话 联络 .

    在Android中,有3个主表:

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

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

    解决方案是,使用 HashMap (而不是a HashSet ),其中键为 CONTACT\u 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);
        }
    }
    
        2
  •  3
  •   IntelliJ Amiya    7 年前

    你可以试试 HashSet .

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

    • 复制 不允许使用值。

    代码结构

     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实现 分类数据集 接口,因此不会出现重复值 允许。

     TreeSet<String> _treeSET= new TreeSet<String>(hashSET);
    
        3
  •  2
  •   Community CDub    4 年前

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

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

    注: 哈希集 可以避免重复输入 more

    哈希集 仅包含唯一元素,可以避免相同的关键元素形式 哈希集

    实例

    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
  •  1
  •   Subhash Prajapati    7 年前

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

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

    您可以添加like ArrayList 在里面 哈希集 :-

    hset.add(your_string);
    

    转换您的 阵列列表 哈希集 :-

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

    哈希集 避免重复输入:)

        5
  •  1
  •   Ashraf Patel    7 年前

    我不知道你为什么从联系人那里得到重复的项目,也许电话联系人已经有重复的值了。您可以在Contacts应用程序中检查这一点。

    在任何需要避免重复项的地方,都应始终使用集合数据结构。你可以找到更好的解释和例子 here .

        6
  •  0
  •   Tejas Pandya    7 年前

    我认为你的复制是因为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
  •  0
  •   Hemant Parmar RubenP5    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);
    

    快乐的编码!!