Более одного LocalDate в месяц в список


Я ввожу проверка аргумента в метод, где один параметр представляет собой список из LocalDate объектов (от Joda времени). Я хочу убедиться, что список содержит более одного LocalDate в месяц.

public List<LocalDate> generateAllDates(List<LocalDate> firstYearDates, ...) { }

Таким образом, например

Arrays.asList(
    new LocalDate(2012, 3, 25),
    new LocalDate(2012, 4, 30),
    new LocalDate(2013, 3, 26)
)

будет нелегальный аргумент, потому что есть две даты, чей месяц-это март.

В настоящее время у меня есть нечто подобное (использование гуавыс Мультикарты):

Multimap<Integer, LocalDate> monthToDates = HashMultimap.create();
for (LocalDate date : firstYearDates) {
    monthToDates.put(date.getMonthOfYear(), date);
}
for (Integer i : monthToDates.keySet()) {
    if (monthToDates.get(i).size() > 1) {
        throw new IllegalArgumentException(
            "firstYearDates must contain at most one entry per month");
    }
}

Вопрос в том, как бы упростить это? Используя любой функции API из комплекта JDK 1.6, гуава или Joda времени нормально.



480
2
задан 18 июля 2011 в 12:07 Источник Поделиться
Комментарии
2 ответа

Немного поздно, но есть гуава встроенный метод для этого - карты.uniqueIndex - дано:

List<LocalDate> dates = Arrays.asList(
new LocalDate(2012,3,25), new LocalDate(2012,4,30), new LocalDate(2013,3,26);

с JDK 8:

Maps.uniqueIndex(dates, LocalDate::getMonthOfYear);

или с JDK <7:

Maps.uniqueIndex(dates, new Function<LocalDate, Integer>() {
@Override
public Integer apply(final LocalDate date) {
return date.getMonthOfYear();
}
});

Он будет бросать

java.lang.IllegalArgumentException: duplicate key: 3

в этом примере.

3
ответ дан 21 июня 2012 в 07:06 Источник Поделиться

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

boolean[] monthFound = new boolean[12];
for(LocalDate date : firstYearDates) {
if(monthFound[date.getMonthOfYear() - 1]) {
throw new IllegalArgumentException(
"firstYearDates must contain at most one entry per month");
} else {
monthFound[date.getMonthOfYear() - 1] = true;
}
}

Если вам нужна карта, то просто проверить containsKey(месяц) перед каждым поставить и бросать исключение, если метод возвращает true.

Если вы просто хотите использовать гуавы, то один из способов сделать это может быть

Function<LocalDate, Integer> months = new Function<LocalDate, Integer>() {    
public Integer apply(LocalDate date) { return date.getMonthOfYear(); }
};

if(new HashSet(Collections2.transform(firstYearDates, months)).size() < firstYearDates.size()) {
throw new IllegalArgumentException(
"firstYearDates must contain at most one entry per month");
}

1
ответ дан 18 июля 2011 в 12:07 Источник Поделиться