使用Collections.binarySearch()进行谓词搜索(即不完全匹配)

时间:2018-08-01 18:48:50

标签: java collections binary-search java-time

我有一个按升序排列的时间戳列表:

Symbol,Series,Date,Prev Close,Open Price,High Price,Low Price,Last Price,Close Price,Average Price,Total Traded Quantity,Turnover,No. of Trades,Deliverable Qty,% Dly Qt to Traded Qty
BIOCON,EQ,2017-07-21,402.6,403,409.55,393.2,399,400.25,401.52,3032146,1217472594,39314,321923,10.62
BIOCON,EQ,2017-07-24,400.25,399,405.9,396.1,399.6,399,401.25,2090835,838941962.6,25520,392951,18.79

现在,给定输入时间戳记List<Instant> timestamps = ...; // note: sorted in ascending order ,我想在Instant inputTs中找到满足t的条目timestamps,即,我只是在寻找{{ 1}},以使t.isBefore(inputTs) && inputTs.isBefore(t.plusMillis(SOME_CONSTANT))位于某个从t开始的固定长度持续时间的范围内。我承认理论上可以有多个这样的inputTs,因此可以在这些搜索之间任意选择。

t重载期望有一个键,指示通用/预期用例将搜索“完全匹配” /相同的条目(缺少更好的用词,对不起)。但是,在我的情况下,tCollections.binarySearch(...)中存在的条目会有所不同,因为预计inputTs将是某个条目{{ 1}}在timestamps中。

我的想法是仅在谓词成立时使提供给inputTs的{​​{1}}返回0:

t

这是解决此问题的正确方法吗?还是我忽略了更好的选择?请注意,对timestamps的调用数量将大大超过Comparator<Instant>中的元素数量,这就是为什么我认为对Collections.binarySearch(...)进行排序会产生开销的原因。

1 个答案:

答案 0 :(得分:4)

Collections.binarySearch 没有用于精确匹配。如文档中所指定,如果找不到完全匹配的内容,它将返回-1 - i,其中i是列表中下一个较高元素的索引。

只需按照自然顺序搜索inputTs。如果找不到,则可以从Instant导出更高的inputTs的索引(只需-1 - resultOfBinarySearch即可)。如果该索引处的Instantbefore(inputTs.plusMillis(CONSTANT)),那么您就完成了,否则,不存在这样的Instant

愿意认为您现有的解决方案滥用了binarySearch,这是值得的。