В зависимости от того, сколько событий и месяцев вы имеете дело за один раз, наивный подход может быть лучшим.Я бы начал с того, что позволил вашим циклам for
обрабатывать итераторы и принял тот факт, что вы будете выполнять (m * n) итераций.Затем, если вы обнаружите, что это место вызывает значительное замедление, вы можете попробовать несколько других методов, чтобы ускорить процесс, не делая ваш код слишком сложным.
Попытка поиска вперед и назад сделает ваш код трудным для понимания и более подверженным ошибкам, не обязательно принося вам много пользы с точки зрения производительности.Обычно вы не заметите существенной разницы в производительности, пока не расскажете не менее чем о сотнях элементов в обеих коллекциях (в этом случае вы можете начать с чего-то простого, например, разбить данные на годы, например, чтобы уменьшить накладные расходыдвойных вложенных for
петель).
Редактировать
Однако, поскольку я просто не могу с собой поделать, вот полус элегантная стратегия, которая потребуетПреимущество того факта, что ваши события и месяцы хранятся в порядке возрастания (я предполагаю, что события хранятся в порядке их даты начала).Он использует LinkedList (который очень эффективен при добавлении и удалении элементов спереди и сзади списка), чтобы отслеживать, какие месяцы может охватывать текущее событие, а затем прерывается, как только находит месяц, который событие не 't включают в себя:
LinkedList<Month> monthList = new LinkedList<Month>();
var i = monthList.getIterator();
for(Event ev : events)
{
shiftList(monthList, i, ev);
for(Month m : monthList)
{
if (!isInMonth(ev, m)) break;
m.addEvent(ev);
}
}
...
// Remove months that are not in scope from the front of the list.
// Add months that are in scope to the end of the list
public void shiftList(LinkedList<Month> monthList, Iterator<Month> i, Event ev)
{
while(!monthList.size() > 0 && !isInMonth(ev, monthList.getFirst()))
{
monthList.removeFirst();
}
while(i.hasNext() && isInMonth(ev, monthList.getLast()))
{
monthList.addLast(i.next());
}
}
Опять же, вы можете видеть, насколько это сложнее: очень вероятно, что я внес ошибку в эту логику, и мне было бы неудобно использовать это в производстве без тщательноготестирование.Вам, как правило, гораздо лучше, если вы просто будете это делать, пока у вас не будет веских причин для оптимизации.