繁体   English   中英

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

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

我正在尝试创建一个时间表,在这里我只能获取输入的时间和时间表名称。

我想将时间表添加到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 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]

示例2:假设列表包含2个项目:

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

我想在列表中从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]

示例3:假设列表包含1个项目:

[08:00 PM] [Some String]

我想在列表中添加从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]

如果没有其他较早的时间,则时间应从06:00 AM开始,否则时间将从该较早的时间开始。

如果没有其他时间,则时间应在5:00 PM结束,否则时间将在该特定时间结束,我只想添加HOUR类的increment小时,因此不应为6:30 : 5:30 6:30 ,除非手动输入。

我正在考虑以下逻辑,但由于想法idea锁而无法进行。

  1. 根据从上午到下午的时间对列表进行排序,以获取第一时间

  2. 检查第一个数据的时间是否等于或小于6:00 AM
    如果为true,则从该时间开始并继续添加缺少的时间,直到5:00 PM或最后一次到达为止。
    如果为假,则从6:00 AM开始并继续添加缺少的时间,直到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;
    }
}

您自己的状态很好。 此外,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]

您必须按照以下步骤

  1. 获取开始的值,它将是06AM或列表的第一个值,这取决于哪个是第一个

  2. 得到end的值,它只是第二个值

  3. 清除列表以删除开始和结束值
  4. 遍历2之间的所有日期,每次递增1h
  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]

不能完全确定您需要什么,但这可能是您需要的:

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

除非要以排序方式显示数据,否则排序没有任何意义。

更新资料

此实现不会阻止您传入分钟(或秒)值的fromto

如果您需要以小时为单位,则可以将其更改为:

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

这将强制两个边界值仅具有小时值。

进行如下

  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的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