2016-12-12 4 views
1

У меня есть метод, который принимает два списка - оба типа Person. Класс Person имеет большое количество атрибутов, но я хочу проверить, содержат ли списки одни и те же элементы только на основе атрибутов name и age, возвращая true, если они равны и false в противном случае.Сравнение элементов в двух отдельных списках в Java

Есть ли лучше, как я могу делать это ?:

public boolean compareTwoLists(List<Person> list1, List<Person> list2) 
{ 
    for (Person person1 : list1) 
    { 
     for (Person person2 : list2) 
     { 
      if (person1.getAge().equals(person2.getAge() && person1.getName().equals(person2.getName()))) 
      { 
       return true; 
      } 
     } 
    } 
    return false; 
} 

ответ

0

Override Object.equals() в классе Person, так что person1.equals(person2) возвращается истина/ложь в зависимости от значений членов.

+0

Единственный способ, которым это могло бы работать, это если метод '.equals()' был переопределен. В противном случае он проверит ссылку на объекты. – CraigR8806

+0

Что делать, если не все участники равны? – ct2602

+0

Я получил это неправильно, спасибо, что указал на это. Обновленный ответ. – SporreKing

0

Отъезд this ответ.

Вы должны применять Comparable. Предполагая, что все поля не быть нулевым (для простоты), что возраст является ИНТ, и сравнить рейтинг является последним, первый, возраст, метод CompareTo довольно прост:

public int compareTo(Person other) { 
    int i = firstName.compareTo(other.firstName); 
    if (i != 0) return i; 

    i = lastName.compareTo(other.lastName); 
    if (i != 0) return i; 

    return Integer.compare(age, other.age); 
} 

Вы могли бы также @Override ваш метод Equals, чтобы сделать его проверить возраст и имя, как этот

public boolean equals(Object p) { 
    ... // More code here - null checks 
    if(p.getName().equals(this.name) && p.getAge() == this.age) 
     return true; 
    else 
     return false; 
} 
0

Если вы хотите сравнить два списка, вам придется перебирать обоих, но если ваши списки сортируются и вы хотите только знать, если они равны аль или нет, то у вас есть только проверить каждый элемент списка в обоих списках один раз, что должно быть намного быстрее, в конце концов, для больших списков:

public boolean compareTwoLists(List<Person> list1, List<Person> list2) { 

    // Lists don't have the same size, objects missing in 
    // list one or two. I your lists have the same size, skip this. 
    if (list1.size() != list2.size() { 
     return false; 
    } 

    Iterator<Person> it1= list1.iterator(); 
    Iterator<Person> it2= list2.iterator(); 

    while (it1.hasNext()) { 
     Person person1 = it1.next(); 
     Person person2 = it2.next(); 

     // Age or name do not match, objects differ, lists are not equal. 
     if ((!person1.next().getAge().equals(person2.getAge()) || (!person1.getName().equals(person2.getName())))) 
      return false; 
    } 

    // All items are the same. 
    return true; 

} 

Кроме того, вы можете написать свой метод как Comparator, что делает его более многоразовые или подходит для сортировки, потому что вы можете вернуть 0 (списки равны), -1 (первый список меньше), 1 (первый список больше) или другие значения для вашей цели:

class PersonListComparator implements Comparator<List<Person>> { 
    @Override public int compare(List<Person> list1, List<Person> list2) { 
     // Your code 
    } 
} 

вы также можете подумайте об переопределении метода equals(...)Person класс, если вы всегда сравнить имя и возраст. Затем сравнение может быть сокращено до person1.equals(person2) в вашем коде.

В качестве альтернативы используйте интерфейс Comparable, который добавляет к вашему классу метод int compareTo(T object), который делает то же самое, что и Comparator.

+0

Добавлена ​​более быстрая альтернатива сортировке, если вы намерены проверить равенство обоих списков. – thatguy

0

Вы возвращаете истину, как только у двух человек одинаковый возраст и имя, но это не значит, что это верно для всех людей.

Для этого в вашем методе вы должны вернуть false, как только сравнение не удастся.
Когда петли закончены, если вы не вернули false, это означает, что все элементы имеют одинаковые значения возраста и имени. Так вы вернетесь true:

public boolean compareTwoLists(List<Person> list1, List<Person> list2){ 
    for (Person person1 : list1) { 
    for (Person person2 : list2) { 
     if (!person1.getAge().equals(person2.getAge() || !person1.getName().equals(person2.getName()))) { 
     return false; 
     } 
    } 
    } 
    return true; 
} 
1

ниже Оба решения в Java 8. Я предпочитаю первый, потому что вы не запутались с классом Person.Но, , если вы абсолютно уверены, что ничего не сломаете, второе решение становится понятным для читателя.

Решение 1

public boolean compareTwoLists(List<Person> list1, List<Person> list2) { 

    return list2.stream().anyMatch(l2 -> list1.stream().anyMatch(l1 -> 
     l1.getName().equals(l2.getName()) && 
     l1.getAge().equals(l2.getAge()) 
    )); 
} 

Раствор 2

public boolean compareTwoLists(List<Person> list1, List<Person> list2) { 
    return list2.stream().anyMatch(list1::contains); 
} 

Это означает, что вам нужно реализовать свои собственные равных и хэш-код внутри объекта Person.

@Override 
    public boolean equals(Object o) 
    { 
     if (this == o) 
      return true; 
     if (o == null || getClass() != o.getClass()) 
      return false; 

     Person person = (Person) o; 

     if (age != null ? !age.equals(person.age) : person.age != null) 
      return false; 
     return name != null ? name.equals(person.name) : person.name == null; 
    } 

    @Override 
    public int hashCode() 
    { 
     int result = age != null ? age.hashCode() : 0; 
     result = 31 * result + (name != null ? name.hashCode() : 0); 
     return result; 
    } 
0

Из вашего вопроса я думаю, что вы просто хотите проверить данный два списка, содержит ли одни и те же данные или нет (такое же количество людей и тех же данных) переназначения хэш-код и составляет методы в классе Person, чтобы проверить только имя и возраст ,

public class Person { 

private String name; 
private int age; 

// other fields 
private String address; 

public String getName() { 
    return name; 
} 

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

public int getAge() { 
    return age; 
} 

public void setAge(int age) { 
    this.age = age; 
} 

public String getAddress() { 
    return address; 
} 

public void setAddress(String address) { 
    this.address = address; 
} 

@Override 
public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + age; 
    result = prime * result + ((name == null) ? 0 : name.hashCode()); 
    return result; 
} 

@Override 
public boolean equals(Object obj) { 
    if (this == obj) 
     return true; 
    if (obj == null) 
     return false; 
    if (getClass() != obj.getClass()) 
     return false; 
    Person other = (Person) obj; 
    if (age != other.age) 
     return false; 
    if (name == null) { 
     if (other.name != null) 
      return false; 
    } else if (!name.equals(other.name)) 
     return false; 
    return true; 
}} 

затем просто передать два списка в данной функции:

public boolean isListEqual(List<Person> list1, List<Person> list2) { 
    if (list1.size() != list2.size()) { 
     return false; 
    } else { 
     for (Person p : list1) { 
      if (!list2.contains(p)) { 
       return false; 
      } 
     } 
     return true; 
    } 
} 
  • Он проверяет, если оба имеют такой же длины в противном случае возвращает ложных
  • еще все лица из первого списка должны быть присутствовать во втором списке, если не возвращать false.
Смежные вопросы