2016-10-05 3 views
2

У меня есть тип OBJ MyObj следующим образом:разница между 2 списками объектов в Java

class MyObj{ 
    String id; 
    String username; 
    String fullName; 
    String age; 

    //getters & setters 
} 

Предположим, что у нас есть 2 списков, содержащих различное число элементов, как так:

List<MyObj> listA 
List<MyObj> listB 

У меня есть который обнаруживает элементы от listA, отсутствующие в listB:

public static <T> List<T> getListDifference(List<T> list1, List<T> list2) { 
     Collection<T> first = new HashSet<T>(list1); 
     Collection<T> second = new HashSet<T>(list2); 
     first.removeAll(second); 
     return new ArrayList<T>(first); 
    } 

Если у объектов от listA и listB есть те же поля для всех предметов, все работает отлично.

Проблема заключается в том, что некоторые пункты есть только id и username но другие могут иметь fullName или age тоже, и в результате этот метод больше не работает. Я хотел бы придерживаться той же логики, учитывая только поле id, потому что оно присутствует во всех объектах.

Один очевидный способ скопировать id только поле объекта в другой List<String> и работать с полученными списками для обнаружения элементов, а затем просто искать OBJ из обоих списков по id. Этот метод имеет большую сложность из-за множества итераций. Есть ли короткий путь для достижения этого?

+8

переопределить 'MyObj # equals' и' MyObj # hashCode' – SomeJavaGuy

+3

Я думаю, что вопрос вообще не связан с Android. – Steeve

ответ

2

Как @ Кевин Esche упоминалось, вы должны реализовать equals() и hashCode() в вашем MyObj POJO, и в соответствии с ситуацией, они должны быть:

@Override 
public int hashCode() { 
    return Objects.hash(id); 
} 

@Override 
public boolean equals(Object obj) { 
    if (obj == this) return true; 
    if (!(obj instanceof MyObj)) return false; 

    MyObj myObj= (MyObj) obj; 
    return Objects.equals(id, myObj.id); 
} 

Это будет работать, даже если возраст различны и идентификаторы одинаковы, например.

+0

clean и simple thx – Choletski

+0

'if (! (Obj instanceof MyObj))' следует заменить на 'if (obj == null || obj.getClass()! = GetClass())'. Потому что, если два объекта данных имеют разные классы, они явно не идентичны. –

2

Для работы с наборами необходимо выполнить equals и hashCode. Множествам нужен способ распознавания, если один объект равен другому, и поведение по умолчанию здесь не будет работать.

Кстати, я предлагаю использовать retainAll метод в списке, check this out.

2

переопределения MyObjs equals метод:

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

    MyObj myObj = (MyObj) o; 

    return (id != null ? !id.equals(myObj.id) : myObj.id != null); 
} 

IntelliJ/Android студии имеют хелперы для автоматической генерации equals и hashCode, где вы можете выбрать необходимые свойства.

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