Я создал приближение к тому, что, я думаю, вы ищете, просто используя Framework Коллекций в Java. Честно говоря, я думаю, что это, вероятно, излишне, как отмечает @Mike Deck. Для такого небольшого набора элементов для сравнения и обработки я думаю, что массивы были бы лучшим выбором с процедурной точки зрения, но вот мое псевдокодированное (потому что я ленивое) решение. У меня есть предположение, что класс Foo сопоставим по его уникальному идентификатору, а не по всем данным в его содержимом:
Collection<Foo> oldSet = ...;
Collection<Foo> newSet = ...;
private Collection difference(Collection a, Collection b) {
Collection result = a.clone();
result.removeAll(b)
return result;
}
private Collection intersection(Collection a, Collection b) {
Collection result = a.clone();
result.retainAll(b)
return result;
}
public doWork() {
// if foo is in(*) oldSet but not newSet, call doRemove(foo)
Collection removed = difference(oldSet, newSet);
if (!removed.isEmpty()) {
loop removed {
Foo foo = removedIter.next();
doRemove(foo);
}
}
//else if foo is not in oldSet but in newSet, call doAdd(foo)
Collection added = difference(newSet, oldSet);
if (!added.isEmpty()) {
loop added {
Foo foo = addedIter.next();
doAdd(foo);
}
}
// else if foo is in both collections but modified, call doUpdate(oldFoo, newFoo)
Collection matched = intersection(oldSet, newSet);
Comparator comp = new Comparator() {
int compare(Object o1, Object o2) {
Foo f1, f2;
if (o1 instanceof Foo) f1 = (Foo)o1;
if (o2 instanceof Foo) f2 = (Foo)o2;
return f1.activated == f2.activated ? f1.startdate.compareTo(f2.startdate) == 0 ? ... : f1.startdate.compareTo(f2.startdate) : f1.activated ? 1 : 0;
}
boolean equals(Object o) {
// equal to this Comparator..not used
}
}
loop matched {
Foo foo = matchedIter.next();
Foo oldFoo = oldSet.get(foo);
Foo newFoo = newSet.get(foo);
if (comp.compareTo(oldFoo, newFoo ) != 0) {
doUpdate(oldFoo, newFoo);
} else {
//else if !foo.activated && foo.startDate >= now, call doStart(foo)
if (!foo.activated && foo.startDate >= now) doStart(foo);
// else if foo.activated && foo.endDate <= now, call doEnd(foo)
if (foo.activated && foo.endDate <= now) doEnd(foo);
}
}
}
Насколько ваши вопросы:
Если я преобразую oldSet и newSet в HashMap (порядок здесь не имеет значения) с идентификаторами в качестве ключей, это облегчит чтение кода и его сравнение? Сколько времени и производительности памяти теряется при конвертации?
Я думаю, что вы, вероятно, сделаете код более читабельным, используя карту, НО ... вы, вероятно, будете использовать больше памяти и времени во время преобразования.
Будет ли итерация двух наборов и выполнение соответствующей операции более эффективной и краткой?
Да, это было бы лучшим из обоих миров, особенно если бы вы следовали совету @Mike Sharek о том, как прокручивать свой собственный список с помощью специализированных методов или следовали чему-то вроде шаблона Visitor Design, чтобы просмотреть вашу коллекцию и обработать каждый элемент.