简体   繁体   English

如何在ObservableList中使用LocalTime添加缺少的时间?

[英]How can I add the missing time using LocalTime in ObservableList?

I am trying to create a scheduling, where I can only get the inputted time and name of schedule. 我正在尝试创建一个时间表,在这里我只能获取输入的时间和时间表名称。

I wanted to put the schedule in a List but if there's no other schedule, the List should be add a new empty schedule starting from 6:00 AM if there's no other early time. 我想将时间表添加到List但是如果没有其他时间表,则如果没有其他早期时间,应该从6:00 AM开始为列表添加一个新的空时间表。

I have ObservableList<DataClass> , it contains LocalTime and some String . 我有ObservableList<DataClass>它包含LocalTime和一些String

Example 1: Let's say the list contains 3 items: 示例1:假设列表包含3个项目:

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

I want to add the missing time in the list from 4:00 AM to 5:00 PM , so the list will be: 我想在列表中从4:00 AM5: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]

Example 2: Let's say the list contains 2 items: 示例2:假设列表包含2个项目:

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

I want to add the missing time in the list from 6:00 AM to 5:00 PM , so the list will be: 我想在列表中从6:00 AM5: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]

Example 3: Let's say the list contains 1 items: 示例3:假设列表包含1个项目:

[08:00 PM] [Some String]

I want to add the missing time in the list from 6:00 AM to 8:00 PM , so the list will be. 我想在列表中添加从6:00 AM8: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]

The time should be start at 06:00 AM if there's no other early time, otherwise the time will start at that early time. 如果没有其他较早的时间,则时间应从06:00 AM开始,否则时间将从该较早的时间开始。

The time should be end at 5:00 PM if there's no other time, otherwise the time will end at that specific time, I want to add only HOUR like increment hour so there shouldn't be 6:30 , 5:30 unless it is manually inputted. 如果没有其他时间,则时间应在5:00 PM结束,否则时间将在该特定时间结束,我只想添加HOUR类的increment小时,因此不应为6:30 : 5:30 6:30 ,除非手动输入。

I am thinking of the following logic but I can't proceed because of lock on idea. 我正在考虑以下逻辑,但由于想法idea锁而无法进行。

  1. Sort the list base on the time from AM to PM to get the first time 根据从上午到下午的时间对列表进行排序,以获取第一时间

  2. Check if the time of the first data is equal or less than 6:00 AM 检查第一个数据的时间是否等于或小于6:00 AM
    if true, then start from that time and continue adding the missing time until the 5:00 PM or the last time is reach. 如果为true,则从该时间开始并继续添加缺少的时间,直到5:00 PM或最后一次到达为止。
    if false, then start from 6:00 AM and continue adding the missing time until the 5:00 PM or the last time is reach. 如果为假,则从6:00 AM开始并继续添加缺少的时间,直到5:00 PM或最后一次到达为止。

the below code is currently what I have and puzzling. 下面的代码是目前我所困惑的。

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: I'm not actually sure what I'm going to ask so feel free to suggest an edit if necessary. PS:我实际上不确定我要问的是什么,因此如有必要,可以随时提出修改建议。

UPDATE: DataClass.class 更新: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;
    }
}

You're well on the way yourself. 您自己的状态很好。 Furthermore azro is correct that you need to find the min and max hour to consider for insertion by comparing to the min and max time already in the data. 此外,azro是正确的,您需要通过与数据中已有的最小和最大时间进行比较来找到要考虑插入的最小和最大小时。 Jai is correct that you should check whether a time is already in the list before inserting it and that a stream is convenient for this purpose. Jai是正确的,您应该在插入列表之前检查列表中是否已经有时间,并且为此目的方便使用流。 My version uses an int for iterating over the hours, but all the others are correct that a LocalTime works too. 我的版本在一个小时内使用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"));
        }
    }

I am assuming that you are sorting the list before and after the above code as in the question. 我假设您正在像问题一样在上述代码之前和之后对列表进行排序。 Sorting before could be omitted if you do a linear traversal for min and max (something a couple of streams can do too). 如果对最小和最大进行线性遍历,则可以省略之前的排序(一些流也可以这样做)。

Sample resulting list: 结果列表示例:

[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]

You have to follow these steps 您必须按照以下步骤

  1. get the value for start, it will be 06AM or the first value of the list, it depends which one is first 获取开始的值,它将是06AM或列表的第一个值,这取决于哪个是第一个

  2. get the value for end, it's just the 2nd value 得到end的值,它只是第二个值

  3. clear the list to remove start and end values 清除列表以删除开始和结束值
  4. iterate over all dates between the 2, incrementing of 1h each time 遍历2之间的所有日期,每次递增1h
  5. the end condition is i.isBefore(end.plusHours(1)) and not i.isBefore(end) because you need the end element to be included 结束条件是i.isBefore(end.plusHours(1))而不是i.isBefore(end)因为您需要包含end元素
  6. sort and print 排序并打印
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]

Not totally sure what you need, but this may be what you need: 不能完全确定您需要什么,但这可能是您需要的:

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);
    }
}

Unless you want to display the data in a sorted manner, there isn't any point in sorting. 除非要以排序方式显示数据,否则排序没有任何意义。

Update 更新资料

This implementation does not stop you from passing in a from and to with minute (or seconds) value. 此实现不会阻止您传入分钟(或秒)值的fromto

If you need it to be in purely hour units, then this can be changed 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);
    }
}

This will force the two boundary values to have only hour values. 这将强制两个边界值仅具有小时值。

Proceed as follows 进行如下

  1. Sort the list 排序清单
  2. Set the time that possibly needs to be inserted (start with the starting with the lower bound of the insertion range) 设置可能需要插入的时间(从插入范围的下限开始)
  3. find the index of the first element with a time >= the time to be inserted 查找时间大于等于要插入的时间的第一个元素的索引
  4. insert a new element at that index, if the element's time does not match the time to be inserted 如果元素的时间与要插入的时间不匹配,则在该索引处插入一个新元素
  5. Modify time to be inserted and continue with 3., if you haven't left the insertion range 修改要插入的时间,然后继续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++;
}

Note that for smaller steps and bigger number of elements in the list the performance of the code is suboptimal, since adding to the middle of the list runs in O(n) , so the resulting complexity would be O(i + i*n + n*log(n)) where i is the number of insertions and n is the initial size of the list. 请注意,对于列表中较小的步骤和较大数量的元素,代码的性能不是最佳的,因为添加到列表的中间是O(n) ,因此结果复杂度为O(i + i*n + n*log(n)) ,其中i是插入次数, n是列表的初始大小。

To improve this, you could add all the new elements to the end of the list and then use the merge step from mergesort once, which would result in runtime O(i+n*log(n)) : 为了改善这一点,您可以将所有新元素添加到列表的末尾,然后使用一次mergesort的merge步骤,这将导致运行时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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM