Как я могу добавить недостающее время, используя LocalTime в ObservableList? - PullRequest
0 голосов
/ 28 июня 2018

Я пытаюсь создать расписание, в котором я могу получить только введенное время и название расписания.

Я хотел бы поместить расписание в List, но если другого расписания нет, в Список следует добавить новое пустое расписание, начиная с 6:00 AM, если другого раннего времени нет.

У меня есть ObservableList<DataClass>, оно содержит LocalTime и немного String.

Пример 1: Допустим, список содержит 3 элемента:

[04:00 AM] [Some String]
[06:30 AM] [Some String]
[05:00 PM] [Some String]

Я хочу добавить недостающее время в списке с 4:00 AM до 5:00 PM, поэтому список будет:

[04:00 AM] [Some String]
[05:00 AM] [Some String]
[06:30 AM] [Some String]
[07:00 AM] [Some String]
[08:00 AM] [Some String]
[09:00 AM] [Some String]
[10:00 AM] [Some String]
[11:00 AM] [Some String]
[12:00 PM] [Some String]
[01:00 PM] [Some String]
[02:00 PM] [Some String]
[03:00 PM] [Some String]
[04:00 PM] [Some String]
[05:00 PM] [Some String]

Пример 2: Допустим, список содержит 2 элемента:

[08:30 AM] [Some String]
[02:00 PM] [Some String]

Я хочу добавить недостающее время в списке от 6:00 AM до 5:00 PM, поэтому список будет:

[06:00 AM] [Some String]
[07:00 AM] [Some String]
[08:00 AM] [Some String]
[09:00 AM] [Some String]
[10:00 AM] [Some String]
[11:00 AM] [Some String]
[12:00 PM] [Some String]
[01:00 PM] [Some String]
[02:00 PM] [Some String]
[03:00 PM] [Some String]
[04:00 PM] [Some String]
[05:00 PM] [Some String]

Пример 3: Допустим, список содержит 1 элемент:

[08:00 PM] [Some String]

Я хочу добавить пропущенное время в списке с 6:00 AM до 8:00 PM, поэтому список будет.

[06:00 AM] [Some String]
[07:00 AM] [Some String]
[08:00 AM] [Some String]
[09:00 AM] [Some String]
[10:00 AM] [Some String]
[11:00 AM] [Some String]
[12:00 PM] [Some String]
[01:00 PM] [Some String]
[02:00 PM] [Some String]
[03:00 PM] [Some String]
[04:00 PM] [Some String]
[05:00 PM] [Some String]
[06:00 PM] [Some String]
[07:00 PM] [Some String]
[08:00 PM] [Some String]

Время должно начинаться с 06:00 AM, если нет другого раннего времени, иначе время начнется в это раннее время.

Время должно заканчиваться на 5:00 PM, если нет другого времени, иначе время закончится в это конкретное время, я хочу добавить только HOUR, например, increment час, поэтому не должно быть 6:30 , 5:30, если он не введен вручную.

Я думаю о следующей логике, но не могу продолжить из-за привязки к идее.

  1. Сортировка базы списка по времени с AM до PM, чтобы получить первый раз

  2. Проверьте, равно ли время первых данных или меньше 6:00 утра
    если истина, то начните с того времени и продолжайте добавлять недостающие время до 17:00 или до последнего раза.
    если ложь, то начать с 6:00 утра и продолжать добавлять недостающее время до 5:00 PM или в последний раз досягаемость.

приведенный ниже код в настоящее время является тем, что у меня есть, и озадачивает.

private void fillTheList(){
        ObservableList<DataClass> data = FXCollections.observableArrayList();
        Comparator<DataClass> comparator = Comparator.comparing(DataClass::getLocalTime);

        data.add(new DataClass(convertTime("05:00 PM"), "Sample Content"));
        data.add(new DataClass(convertTime("06:30 AM"), "Sample Content"));

        FXCollections.sort(data,comparator); //Sort the list from AM to PM

        for (DataClass list : data){
            if(list.getLocalTime().isBefore(LocalTime.of(6,0))){
                //The time is less than 6:00 AM then it should start here and Add the missing time but I don't know what to do next...
            }else{
                //the time is not less than 6:00 AM... I don't know what to do next..
            }
        }
        FXCollections.sort(data,comparator); //Sort the list from AM to PM again
}

private LocalTime convertTime(String timeString){
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a");
        return LocalTime.parse(timeString, formatter);
}

PS: На самом деле я не уверен, что собираюсь спросить, поэтому не стесняйтесь предлагать правку, если это необходимо.

ОБНОВЛЕНИЕ: DataClass.class

public class DataClass {

    private LocalTime localTime;
    private String content;

    public DataClass(LocalTime localTime, String content){
        this.localTime = localTime;
        this.content = content;
    }

    public LocalTime getLocalTime(){
        return localTime;
    }

    public String getContent(){
        return content;
    }
}

Ответы [ 4 ]

0 голосов
/ 28 июня 2018

Ты сам в пути. Кроме того, azro правильно, что вам нужно найти минимальный и максимальный час, который нужно учесть для вставки, сравнивая минимальное и максимальное время уже в данных. Jai правильно, что вы должны проверить, есть ли время в списке, прежде чем вставлять его, и что поток удобен для этой цели. Моя версия использует int для итерации по часам, но все остальные верны, что LocalTime тоже работает.

    int minHour = 6;
    int maxHour = 17;
    if (! data.isEmpty()) {
        // adjust min and max from list contents
        int minExisintgHour = data.get(0).getLocalTime().getHour();
        if (minExisintgHour < minHour) {
            // if the list already contained 4:00 or 4:30,
            // we only need to add hours from 5, so add 1
            minHour = minExisintgHour + 1;
        }
        int maxExisintgHour = data.get(data.size() - 1).getLocalTime().getHour();
        if (maxExisintgHour > maxHour) {
            maxHour = maxExisintgHour;
        }
    }
    for (int hour = minHour; hour <= maxHour; hour++) {
        LocalTime time = LocalTime.of(hour, 0);
        boolean alreadyInData = data.stream().anyMatch(d -> d.getLocalTime().equals(time));
        if (! alreadyInData) {
            data.add(new DataClass(time, "Added beacuse time was missing"));
        }
    }

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

Пример списка результатов:

[06:00 AM] [Added beacuse time was missing]
[06:30 AM] [Sample Content]
[07:00 AM] [Added beacuse time was missing]
[08:00 AM] [Added beacuse time was missing]
[09:00 AM] [Added beacuse time was missing]
[10:00 AM] [Added beacuse time was missing]
[11:00 AM] [Added beacuse time was missing]
[12:00 PM] [Added beacuse time was missing]
[01:00 PM] [Added beacuse time was missing]
[02:00 PM] [Added beacuse time was missing]
[03:00 PM] [Added beacuse time was missing]
[04:00 PM] [Added beacuse time was missing]
[05:00 PM] [Sample Content]
0 голосов
/ 28 июня 2018

Не совсем уверен, что вам нужно, но это может быть то, что вам нужно:

ObservableList<DataClass> data = FXCollections.observableArrayList();

// Need to specify the period that you want the entries to be filled
private void fill(LocalTime from, LocalTime to) {
    // Keep adding new entries until we have reached the end
    while (!from.isAfter(to)) {
        // We need a final variable for stream()
        final LocalTime temp = from;

        // If data does not contain any time that is equivalent to this time
        if (data.stream().noneMatch(d -> temp.equals(d.getLocalTime()))) {
            data.add(new DataClass(temp, "Hello World"));
        }

        // Increment the time by an hour, and wait for next loop cycle
        from = from.plusHours(1);
    }
}

Если вы не хотите отображать данные в отсортированном виде, сортировка не имеет смысла.

Обновление

Эта реализация не мешает вам передавать значения from и to в минутах (или секундах).

Если вам нужно, чтобы он был в чисто часовых единицах, то это можно изменить на:

ObservableList<DataClass> data = FXCollections.observableArrayList();

// Need to specify the period that you want the entries to be filled
private void fill(int fromHour, int toHour) {
    LocalTime from = LocalTime.of(fromHour, 0);
    LocalTime to = LocalTime.of(toHour, 0);

    // Keep adding new entries until we have reached the end
    while (!from.isAfter(to)) {
        // We need a final variable for stream()
        final LocalTime temp = from;

        // If data does not contain any time that is equivalent to this time
        if (data.stream().noneMatch(d -> temp.equals(d.getLocalTime()))) {
            data.add(new DataClass(temp, "Hello World"));
        }

        // Increment the time by an hour, and wait for next loop cycle
        from = from.plusHours(1);
    }
}

Это заставит два граничных значения иметь только часовые значения.

0 голосов
/ 28 июня 2018

Действуйте следующим образом

  1. Сортировка списка
  2. Установите время, которое, возможно, необходимо вставить (начните со старта с нижней границы диапазона вставки)
  3. найти индекс первого элемента со временем> = время для вставки
  4. вставить новый элемент по этому индексу, если время элемента не соответствует времени, которое нужно вставить
  5. Измените время для вставки и продолжайте с 3., если вы не вышли из диапазона вставки
ObservableList<DataClass> data = ...
LocalTime lowerBound = LocalTime.of(6, 0); // or some other input
LocalTime upperBound = LocalTime.of(12 + 5, 0); // or some other input


Comparator<DataClass> comparator = Comparator.comparing(DataClass::getLocalTime);
FXCollections.sort(data, comparator);

int size = data.size();
int index = 0;

while (!lowerBound.isAfter(upperBound)) {
    // find inserting index
    while (index < size && data.get(index).getLocalTime().isBefore(lowerBound)) {
        index++;
    }
    // insert, if not already in list
    if (index >= size || !data.get(index).getLocalTime().equals(lowerBound)) {
        data.add(index, new DataClass(lowerBound, "Inserted"));
        size++;
    }
    lowerBound = lowerBound.plusHours(1);
    index++;
}

Обратите внимание, что при меньших шагах и большем количестве элементов в списке производительность кода оказывается неоптимальной, поскольку добавление в середину списка выполняется в O(n), поэтому сложность будет равна O(i + i*n + n*log(n)), где i - количество вставок, n - начальный размер списка.

Чтобы улучшить это, вы можете добавить все новые элементы в конец списка, а затем один раз использовать шаг слияния из mergesort, что приведет к времени выполнения O(i+n*log(n)):

final int size = data.size();
int index = 0;

while (!lowerBound.isAfter(upperBound)) {
    // find inserting index
    while (index < size && data.get(index).getLocalTime().isBefore(lowerBound)) {
        index++;
    }
    // insert, if not already in list
    if (index >= size || !data.get(index).getLocalTime().equals(lowerBound)) {
        data.add(new DataClass(lowerBound, "Inserted"));
    } else {
        index++;
    }
    lowerBound = lowerBound.plusHours(1);
}

// merge
DataClass[] merged = new DataClass[data.size()];
int insertionIndex = 0;
int index1 = 0;
int index2 = size;
while (index1 < size && index2 < merged.length) {
    DataClass v1 = data.get(index1);
    DataClass v2 = data.get(index2);
    if (v2.getLocalTime().isBefore(v1.getLocalTime())) {
        merged[insertionIndex] = v2;
        index2++;
    } else {
        merged[insertionIndex] = v1;
        index1++;
    }
    insertionIndex++;
}

// copy remaining
while (index1 < size) {
    merged[insertionIndex++] = data.get(index1++);
}
while (index2 < merged.length) {
    merged[insertionIndex++] = data.get(index2++);
}
data.setAll(merged);
0 голосов
/ 28 июня 2018

Вы должны выполнить следующие действия

  1. получить значение для запуска, оно будет 06AM или первое значение в списке, это зависит от того, какое из них является первым

  2. получить значение для конца, это просто 2-е значение

  3. очистить список для удаления начальных и конечных значений
  4. итерация по всем датам между 2, с шагом 1 час каждый раз
  5. конечным условием является i.isBefore(end.plusHours(1)), а не i.isBefore(end), поскольку необходимо включить элемент end
  6. сортировка и печать
ObservableList<DataClass> data = FXCollections.observableArrayList();
Comparator<DataClass> comparator = Comparator.comparing(DataClass::getLocalTime);

data.add(new DataClass(convertTime("05:00 PM"), "Sample Content"));
data.add(new DataClass(convertTime("06:30 AM"), "Sample Content"));

FXCollections.sort(data,comparator); //Sort the list from AM to PM
// 1. & 2.
LocalTime begin = LocalTime.of(6,0);
if(data.get(0).getLocalTime().isBefore(begin)){
   begin = data.get(0).getLocalTime();
}

LocalTime end = LocalTime.of(17,0);
if(end.isBefore(data.get(data.size()-1).getLocalTime())){
    end = data.get(data.size()-1).getLocalTime();
}

// 3.
data.clear();
// 4. & 5.
for(LocalTime i = begin.withMinute(0); !i.isAfter(end); i = i.plusHours(1)){
   data.add(new DataClass(i, "Sample Content"));        
}

// 6. 
FXCollections.sort(data,comparator); //Sort the list from AM to PM again
System.out.println(data);
//  [06:00, 07:00, 08:00, 09:00, 10:00, 11:00, 12:00, 13:00, 14:00, 15:00, 16:00, 17:00]
...