Пересечение интервалов времени Java

386
24 октября 2017, 00:03

Нужно определить, пересекаются ли два интервала времени между собой. Если да, то нужно это вывести на консоль. Предположим есть два события, с начальной датой, начальным и конечным временем:

  1. Событие 1 [23.10.2017 10:00, 23.10.2017 11:00].
  2. Событие 2 [23.10.2017 09:00, 23.10.2017 10:00].

Как видно они пересекаются. Я написал код который проверяет это через if <> операторы.

Вопрос в том, есть ли другой путь написать логику, что бы, например, можно было добавлять дополнительно 5 событий с разными интервалами? Например, можно ли поместить события в Array и написать логику чтобы проверка происходила из Array? Или какой-то другой путь.

Результатом должны стать все пары пересечений этих интервалов.

Answer 1
  1. Прогоняем массив интервалов.
  2. В нём прогоняем его ещё раз в другом цикле.
  3. Смотрим, пересекаются ли.
  4. Если да, то проверяем дубли и т.п.
  5. Если такого пересечения ещё нет, то добавляем в массив.

Примерная реализация в лоб без всяких оптимизаций и т.п:

public static class Intercection {
    private Interval mFirst;
    private Interval mSecond;
    public Intercection(Interval first, Interval second) {
        mFirst = first;
        mSecond = second;
    }
    public Interval getFirst() {
        return mFirst;
    }
    public Interval getSecond() {
        return mSecond;
    }
    public boolean equals(Intercection another){
        return (mFirst.equals(another.mFirst) && mSecond.equals(another.mSecond)) || (mSecond.equals(another.mFirst) && mFirst.equals(another.mSecond));
    }
    public String toString() {
        return "[" + mFirst.toString() + " => " + mSecond.toString() + "[";
    }
}
public static class Interval {
    private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm z");
    private ZonedDateTime mFrom;
    private ZonedDateTime mTo;
    public Interval(String from, String to){
        mFrom = ZonedDateTime.parse(from, DATE_FORMAT);
        mTo = ZonedDateTime.parse(to, DATE_FORMAT);
    }
    public static List<Intercection> getIntercection(List<Interval> intervals){
        int count = intervals.size();
        List<Intercection> intercections = new ArrayList<App.Intercection>();
        // находим для каждого интервала пересечения с другими интервалами
        for (int i = 0; i < count; i++) {
            Interval curInterval = intervals.get(i);
            for (int j = 0; j < count; j++) {
                // скипаем сравнение с самим собой
                if(curInterval == intervals.get(j))
                    continue;
                Intercection inter = new Intercection(curInterval, intervals.get(j));
                // скипаем интервалы от повторого добавления
                if(curInterval.hashasIntercection(intervals.get(j)) && !intercections.stream().anyMatch(interscection -> interscection.equals(inter))){
                    intercections.add(inter);
                }
            }
        }
        return intercections;
    }
    public boolean equals(Interval another){
        return mFrom.equals(another.mFrom) && mTo.equals(another.mTo);
    }
    /**
     * проверка на то, пересекаются ли интервалы
     * @param interval
     * @return
     */
    public boolean hashasIntercection(Interval interval){
        return mFrom.equals(interval.mFrom) || (mFrom.isBefore(interval.mFrom) && mTo.isAfter(interval.mFrom)) || (mFrom.isAfter(interval.mFrom) && mFrom.isBefore(interval.mTo));
    }
    public String toString() {
        return "{" + mFrom.format(DATE_FORMAT) + ":" + mTo.format(DATE_FORMAT) + "]";
    }
}

Использовать так:

    List<Interval> intervals = new ArrayList<App.Interval>();
    intervals.add(new Interval("23.10.2017 10:00 Z", "23.10.2017 11:00 Z"));
    intervals.add(new Interval("21.10.2017 10:30 Z", "25.10.2017 11:00 Z"));
    intervals.add(new Interval("23.10.2017 10:20 Z", "23.10.2017 11:00 Z"));
    // все пары пересечений     
    List<Intercection> intercections = Interval.getIntercection(intervals);
    intercections.forEach(inter -> System.out.println(inter.toString()));
READ ALSO
Синхронизация android устройства и пк

Синхронизация android устройства и пк

Доброго времени суток!Нужно создать клиент-серверное приложение,сервером которого будет выступать ПК(на windows),а клиентом android-устройствоПроблема...

214
Ругается на ломбок

Ругается на ломбок

Здравствуйте, подскажите в чем причина ошибкиРугается на ломбок

358
Задача на потоки

Задача на потоки

В самом условии: есть гостиница с номерами; клиент приходит, заселяется в номер или ждет пока освободится, если все занятоКакое-то время живет...

227
Как объявить несколько переменных @FXML

Как объявить несколько переменных @FXML

это не очень удобно, хотелось бы не повторять несколько раз @FXML

181