package de.saring.util.data; import java.time.LocalDate; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; /** * This list extends IdObjectList and contains unique instances of IdDateObject * subclasses. It and will also never contain multiple instances with the same * ID. The list is always sorted by the date of the IdDateObject instances. * * @param <T> the object type to store in this list, must be a subclass of * IdDateObject * @author Stefan Saring * @version 1.0 */ public class IdDateObjectList<T extends IdDateObject> extends IdObjectList<T> { /** * Stores the specified IdDateObject object in list. It will be inserted * into the correct list position, so that all IdDateObject's are sorted * ascending by date. When there's allready an IdDateObject object with the * same ID then the old IdDateObject will be removed from list before. * * @param t IdDateObject instance to store (must not be null and must have a * date) */ @Override public void set(T t) { validateEntry(t); // remove the object in the list if it's allready stored (same ID) getIDObjects().remove(t); try { // insert the object by date order (or add it to the end) for (int i = 0; i < getIDObjects().size(); i++) { IdDateObject temp = getIDObjects().get(i); if (t.getDateTime().isBefore(temp.getDateTime())) { getIDObjects().add(i, t); return; } } getIDObjects().add(t); } finally { notifyAllListChangelisteners(t); } } /** * Clears this IdDateObjectList and adds all IdDateObjects of the passed list. * This list will be sorted afterwards, ascending by date. Finally all registered * ChangeListeners will be notified. * * @param entries list of IdDateObjects to store (must not be null, entries must not be null and all * entries and must have a valid ID and a date) */ @Override public void clearAndAddAll(final List<T> entries) { Objects.requireNonNull(entries, "List of IdDateObjects must not be null!"); entries.forEach(entry -> validateEntry(entry)); getIDObjects().clear(); getIDObjects().addAll(entries); getIDObjects().sort((entry1, entry2) -> entry1.getDateTime().compareTo(entry2.getDateTime())); notifyAllListChangelisteners(null); } /** * Returns all IdDateObject entries of this list for which their datetime is in * the specified date range. * * * @param dStart start date of the time range (inclusive) * @param dEnd end date of the time range (inclusive) * @return list of entries in this time range */ public List<T> getEntriesInDateRange(LocalDate dStart, LocalDate dEnd) { Objects.requireNonNull(dStart, "Start date must not be null"); Objects.requireNonNull(dEnd, "End date must not be null"); if (dStart.isAfter(dEnd)) { throw new IllegalArgumentException("Start date is after end date!"); } return stream().filter(dateObject -> { LocalDate doDate = dateObject.getDateTime().toLocalDate(); return !doDate.isBefore(dStart) && !doDate.isAfter(dEnd); }).collect(Collectors.toList()); } @Override protected void validateEntry(final T t) { super.validateEntry(t); Objects.requireNonNull(t.getDateTime(), "DateTime must not be null!"); } }