有效搜索连续日期的列表

时间:2018-05-03 14:21:34

标签: java performance search

我的结构包含连续的时间段(没有重叠)和一定的值。

class Record {
    private TimeWindow timeWindow;
    private String value;
}

interface TimeWindow {
    LocalDate getBeginDate();

    LocalDate getEndDate(); //Can be null
}

我的目标是实现一个日期并计算出价值的函数。 一个天真的实现可能是遍历所有记录,直到日期与窗口匹配。

class RecordHistory {
    private List<Record> history;

    public String getValueForDate(LocalDate date) {
        for (Record record : history) {
            if (record.dateMatchesWindow(date)){
                return record.getValue();
            }
        }

        return null; //or something similar
    }
}

class Record {

    private TimeWindow timeWindow;
    private String value;

    public boolean dateMatchesWindow(LocalDate subject) {
        return !subject.isBefore(timeWindow.getBeginDate()) && (timeWindow.getEndDate() == null || !subject.isAfter(timeWindow.getEndDate()));
    }

    public String getValue(){
        return value;
    }
}

这些值的来源来自数据库查询(无法更改表的结构)。记录列表可能很小或很大,日期从历史开始到结束不等。但是,对于同一RecordHistory,同一日期不会计算两次。将有多个RecordHistory对象,这些值代表不同的属性。

有没有一种有效的方法来搜索这个结构?

1 个答案:

答案 0 :(得分:1)

您可以使用binary search在O(logn)时间内获取匹配的Record(如果存在此类记录)。

Java已经有了适合您的数据结构,例如TreeMap。您可以将每个Record映射到其开始时间,然后在给定时间内获得floorEntry,并查看它是否匹配。

// create map (done only once, of course)
TreeMap<LocalDate, Record> records = new TreeMap<>();
for (Record r : recordList) {
    records.put(r.getTimeWindow().getBeginDate(), r);
}

// find record for a given date
public String getValueForDate(LocalDate date) {
    Record floor = records.floorEntry(date).getValue();
    if (floor.dateMatchesWindow(date)) {
        return r;
    }
    return null;
}

如果条目不重叠,并且楼层条目匹配,则不会有其他条目。