Как получить список DayOfWeek между двумя DayOfWeeks - PullRequest
4 голосов
/ 19 апреля 2020

Я хочу получить список DayOfWeeks, между двумя DayOfWeeks.

Например,

Input1: DayOfWeek.MONDAY
Input2: DayOfWeek.WEDNESDAY

И вывод должен быть список

[DayOfWeek.MONDAY, DayOfWeek.TUESDAY,
DayOfWeek.WEDNESDAY]

Is Java предоставляет какой-либо API для этого?

Ответы [ 4 ]

2 голосов
/ 19 апреля 2020

Пересечение границы недели

Другие ответы хороши (мне особенно нравится решение EnumSet Базиля Бурка ). Кажется, все они предполагают (1), что ваши два входных дня находятся в одной и той же неделе, и (2) что неделя начинается в понедельник, как перечисление DayOfWeek. А что, если входными данными были пятница и понедельник, мы бы не хотели пятница, суббота, воскресенье, понедельник ? Что если пользователь в США и ожидает, что воскресенье и вторник принесут воскресенье, понедельник, вторник ? Воскресенье - первый день недели там (и в некоторых других местах также).

Я думаю, что с учетом этих возможностей нет лучшего решения, чем классический l oop.

    DayOfWeek input1 = DayOfWeek.FRIDAY;
    DayOfWeek input2 = DayOfWeek.MONDAY;

    List<DayOfWeek> range = new ArrayList<>(7);
    DayOfWeek currentDow = input1;
    range.add(currentDow);
    while (! currentDow.equals(input2)) {
        currentDow = currentDow.plus(1);
        range.add(currentDow);
    }

    System.out.println(range);

Вывод:

[ПЯТНИЦА, Суббота, воскресенье, понедельник]

Поскольку я использую список, а не набор, дни приходят в порядок. К счастью, метод plus имеет переполнение циклического c: SUNDAY.plus(1) дает MONDAY, первый член перечисления.

Не пересекает границу недели

Если требуется, чтобы вы не переходили на следующую неделю (с воскресенья по понедельник), вам следует проверить, что ваши входные данные соответствуют требованию, а затем использовать один из других ответов. Пример проверки:

    if (input1.getValue() > input2.getValue()) {
        throw new IllegalStateException("Inputs muct be in chronological order within the same Monday-based week");
    }
2 голосов
/ 19 апреля 2020

Вы можете получить дни, используя DayOfWeek.values ​​() , а затем используйте filter, чтобы отфильтровать дни между MONDAY и WEDNESDAY

List<DayOfWeek> days = Arrays.stream(DayOfWeek.values())
            .filter(day -> day.getValue() >= DayOfWeek.MONDAY.getValue()
                    && day.getValue() <= DayOfWeek.WEDNESDAY.getValue())
            .collect(Collectors.toList());

    System.out.println(days);
1 голос
/ 19 апреля 2020

tl; др

EnumSet.range( DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY )

EnumSet.range

EnumSet - это реализация Set, оптимизированная для работы с объекты enum.

EnumSet.range создает подмножество объектов enum в порядке их определения. Для DayOfWeek этот порядок - понедельник-воскресенье, согласно стандарту ISO 8601 .

Диапазон полностью закрыт, означая как начало, так и конец

Set<DayOfWeek> set = EnumSet.range( DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY );

set.toString (): [ПОНЕДЕЛЬНИК, ВТОРНИК, СРЕДА]

Если в проблемном домене используется порядок дней, отличный от понедельника- В воскресенье см. Ответ от Ole VV

Если вам действительно нужен List вместо Set, конвертируйте. Передайте набор конструктору реализации List, такой как ArrayList.

List< DayOfWeek > dows = new ArrayList<>( set );
1 голос
/ 19 апреля 2020

Это один из способов, которым вы можете достичь этого. Там может быть лучший способ. Вы создаете значения потока целых чисел, где начало - это первый день, а последний - последний день + 1. Затем сопоставьте объект DayOfWeek со значением дня.

        DayOfWeek monday = DayOfWeek.MONDAY;

        DayOfWeek wednesday = DayOfWeek.WEDNESDAY;

        List<DayOfWeek> days = IntStream.range(monday.getValue(), wednesday.getValue() + 1)
                .mapToObj(DayOfWeek::of)
                .collect(Collectors.toList());

Выход

[MONDAY, TUESDAY, WEDNESDAY]
...