2016-06-10 8 views
0

У меня есть 2 ArrayList. И мне нужны элементы с общими phone.общие объекты в 2 ArrayList

ArrayList<Contact> phone_contacts; 
ArrayList<Contact> registered_users; 

Я использовал ниже метод, чтобы получить общие элементы:

ArrayList<Contact> common_contacts = new ArrayList<Contact>(phone_contacts); 
common_contacts.retainAll(registered_users); 

Но результат я получаю пустой. Как я могу получить общий телефонный контакт в common_contacts ArrayList?

Контакт

public class Contact { 
    private String name; 
    private String phone; 

    public Contact(String name, String phone) { 
     this.name = name; 
     this.phone = phone; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getPhone() { 
     return phone; 
    } 

    public void setPhone(String phone) { 
     this.phone = phone; 
    } 
} 
+0

Вам необходимо переопределить соответствующие равных() и хэш-код() реализации Контакты класс, чтобы сделать эту работу. JVM использует реализацию equals() для сравнения двух объектов одинаковыми или нет. – kosa

+0

@ Nambari: Как я могу это сделать? Я новичок в java. –

+0

http://www.javaworld.com/article/2073330/the-contains-trap-in-java-collections.html может быть хорошим примером/ – kosa

ответ

2

Во-первых, если вы лечите номер телефона в качестве идентификатора, я бы советовал соблюдать осторожность. Falsehoods Programmers Believe About Phone Numbers

С учетом сказанного ...

retainAll в конечном счете использует метод equals. Учитывая, что у вас есть пользовательский объект (а не что-то вроде String или int, которые имеют определенный equals), самым простым методом было бы определить метод equals для Contact, который возвращает true, если два имеют одинаковый номер телефона.

Однако, возможно, это не то, что вы ищете. Например, equals, возможно, потребуется проверить имя в других контекстах.

Есть несколько других подходов, которые вы могли бы предпринять. Поскольку вы упомянули Android, потоки Java 8 в настоящее время отсутствуют. Цикл Iterator может выполнить эту работу. Соберите все номера телефонов для зарегистрированных пользователей в Set (так что у вас есть уникальный список), затем начните с List всех ваших контактов и удалите все, у которых нет номера телефона из этого набора.

Set<String> registeredPhoneNumbers = new HashSet<>(); 
for (Contact c : registered_users) { 
    registeredPhoneNumbers.add(c.getPhone()); 
} 
List<Contact> common_contacts = new ArrayList<>(phone_contacts); 
for (Iterator<Contact> iter = common_contacts.iterator(); iter.hasNext();) { 
    Contact c = iter.next(); 
    if (!registeredPhoneNumbers.contains(c.getPhone())) { 
    iter.remove(); 
    } 
} 

Поскольку вы упомянули в комментариях, что может быть миллион различных registered_users, это могло бы быть более эффективным пространство:

Set<String> phoneNumbers = new HashSet<>(); 
for (Contact c : phone_contacts) { 
    phoneNumbers.add(c.getPhone()); 
} 

Set<String> overlappingNumbers = new HashSet<>(); 
for (Contact registered : registered_users) { 
    if (phoneNumbers.contains(registered.getPhone())) { 
     overlappingNumbers.add(registered.getPhone()); 
    } 
} 
List<Contact> common_contacts = new ArrayList<>(); 
for (Contact contact : phone_contacts) { 
    if (overlappingNumbers.contains(contact.getPhone())) { 
     common_contacts.add(contact); 
    } 
    } 
} 

Вы можете проверить номер телефона нуль, а также.

+0

Что такое 'c' и' iter' в if loop? 'if (! registeredPhoneNumbers.contains (c.getPhone())) { iter.remove(); } ' –

+0

То, что я получаю для записи цикла Iterator, когда все, что я делаю, это Java 8 в наши дни. Исправлена. –

+0

Он работает нормально. Благодаря! У меня только один вопрос. Является ли это эффективным методом, если у меня есть 1 миллион 'registered_users' и сотни' phone_contacts'? –

0

Если вы используете метод RetainAll в Перечислите вы получите общие объекты между 2 списками .. \

Пример:

рассмотреть списки целые числа (только для примера) он будет работать с вашим классом ...

public static void main(String[] args) { 
    List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(0, 1, 2, 3, 4, 5)); 
    List<Integer> list2 = new ArrayList<Integer>(Arrays.asList(1, 3, 5)); 
    List<Integer> list3 = new ArrayList<Integer>(list1); 
    list3.retainAll(list2); 
    System.out.println("List1:" + list1); 
    System.out.println("List2:" + list2); 
    System.out.println("List common:" + list3); 

    } 

В вашем случае классовыми контактов необходимо изменить таким образом, метод ArrayLst.retainAll() может как-то идентифицировать Контакт ли такой же, как другой, используя в качестве критериев номер телефона ...

Изменить/улучшения контакта класса путем добавления Hashcode и Равно:

но вы должны использовать в качестве критерия только номер телефона

public class Contact { 
    private String name; 
    private int phone; 

    public Contact(String name, int phone) { 
    this.name = name; 
    this.phone = phone; 
    } 

    public String getName() { 
    return name; 
    } 

    public void setName(String name) { 
    this.name = name; 
    } 

    @Override 
    public String toString() { 
    return "Contact [name=" + name + ", phone=" + phone + "]"; 
    } 

    @Override 
    public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + phone; 
    return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
    if (this == obj) 
     return true; 
    if (obj == null) 
     return false; 
    if (getClass() != obj.getClass()) 
     return false; 
    Contact other = (Contact) obj; 
    if (phone != other.phone) 
     return false; 
    return true; 
    } 

    public int getPhone() { 
    return phone; 
    } 

    public void setPhone(int phone) { 
    this.phone = phone; 
    } 
} 

Реализовать список контактов и вызвать метод RetainAll

public static void main(String[] args) { 
    List<Contact> list1 = new ArrayList<Contact>(Arrays.asList(new Contact(UUID.randomUUID().toString(), 1), 
     new Contact(UUID.randomUUID().toString(), 2), new Contact(UUID.randomUUID().toString(), 3), 
     new Contact(UUID.randomUUID().toString(), 4), new Contact(UUID.randomUUID().toString(), 5))); 
    List<Contact> list2 = new ArrayList<Contact>(Arrays.asList(new Contact(UUID.randomUUID().toString(), 1), 
     new Contact(UUID.randomUUID().toString(), 3), new Contact(UUID.randomUUID().toString(), 5))); 
    List<Contact> list3 = new ArrayList<Contact>(list1); 
    list3.retainAll(list2); 
    System.out.println("List1:" + list1); 
    System.out.println("List2:" + list2); 
    System.out.println("List common:" + list3); 
    } 
+0

Мне нужен только обычный телефон. Не весь объект. Есть ли способ изменить это? –

+0

Тег говорит Android, так что нет. –

Смежные вопросы