Java 基于时间的分组
我有以下问题: 我有一个对象列表(包含一个日期属性),大小为S(通常S会达到200k左右,但有时可能会达到一百万) 我需要根据以下条件筛选列表:Java 基于时间的分组,java,algorithm,Java,Algorithm,我有以下问题: 我有一个对象列表(包含一个日期属性),大小为S(通常S会达到200k左右,但有时可能会达到一百万) 我需要根据以下条件筛选列表: 只有从日期属性开始,在时间间隔T内的列表X事件中才能找到项目,该项目才必须保留在最终列表中 考虑到大量的列表以及低效的解决方案可能会产生哪些性能问题,请您告诉我解决此问题的最佳方法/算法 谢谢 PS:实现是用JAVA实现的,我不认为我完全理解您的问题,但是如果列表按日期排序,您应该能够确定以下X项是否都在时间间隔t内,否则请删除它们 如果X变高,您
- 只有从日期属性开始,在时间间隔T内的列表X事件中才能找到项目,该项目才必须保留在最终列表中
PS:实现是用JAVA实现的,我不认为我完全理解您的问题,但是如果列表按日期排序,您应该能够确定以下X项是否都在时间间隔t内,否则请删除它们
如果X变高,您可能会考虑使用不同的排序结构,例如<代码>树贴图,其中键是日期。然后你可以这样做:
SortedMap<Date, YourObject> map = ...;//left for you
int numEventsInInterval = map.subMap( intervalStart, intervalEnd ).size();
SortedMap=//留给你的
int numEventsInInterval=map.subMap(intervalStart,intervalEnd.size();
您需要:
class Foo { Date date; }
class Event { Period period; }
class Period { Date start, end; }
List<Foo> foos = ...
List<Event> events = ...
Period p = new Period(...)
[pseudo-code]
foreach foo in foos:
eventsAfterFoo = findEventsAfter(foo.date, events);
c = 0;
foreach event in eventsAfterFoo:
if(event.isInPeriod(p)) c++
if(c >= X)
finalList.add(foo)
class Foo{Date;}
类事件{Period Period;}
类周期{日期开始,结束;}
列表foos=。。。
列出事件=。。。
期间p=新期间(…)
[伪代码]
foos中的foreach foo:
eventsAfterFoo=findEventsAfter(foo.date,events);
c=0;
eventsAfterFoo中的foreach事件:
If(事件IsI期(p))C++
如果(c>=X)
finalList.add(foo)
对于大量元素,您肯定会使用数据库简化您的解决方案,即使是像HSQL这样的非主流数据库
您当然可以将列表拆分为不同机器上的不同VM,唯一的共享/只读列表是“事件” 在完整列表中遍历长度为X的子列表 在每次迭代中: 如果sublist.tail.date-sublist.head.date>T,则标记sublist.head以丢弃
不幸的是,你最终可能会放弃一些资格赛,但这是可以解决的。我可能完全错了,但我认为人们忽略了一个事实,即你的标题使用了“分组”而不是“筛选”,以及“从日期属性开始”的部分。以下是我对你的问题的看法:
- 您有一个源列表L,其中包含具有时间戳属性t的I类型的项
- 您希望构造一个目标列表T,其中包含来自L的项(可能顺序相同)
- 您有一些半径r,表示为时间单位(毫秒、秒、分钟…)
- 您有一些正整数阈值l(这里没有字母了)
- 当且仅当L中有L个或多个时间戳在区间[i.T-r,i.T+r]内的项目时,L中的项目i应放置在T中
Comparable
接口,并且按照时间戳进行排序,那么它将很简单。否则,您可能需要实现一个对timestamp属性进行排序的比较器。排序的性能不能比O(n*logn)更好,所以这是目前的底线
编辑:我刚刚意识到你的字面意思可能是“从开始”,所以如果是这样的话,只需忽略尾随索引s,只处理前导索引e。除采用(e-c)而不是(e-s)外,该算法在其他方面保持不变。我在预编辑版本中也有一些“框架列表”,这显然是无稽之谈,因为索引足以计算所需的数量。您可以通过监视器“流式”对象(我称之为事件),监视器用所需属性标记事件 例如:
public class EventMonitor {
private int minimumGroupSize;
private long window;
private LinkedList<Event> events = new LinkedList<Event>();
public EventMonitor(int minimumGroupSize, long window) {
this.minimumGroupSize = minimumGroupSize;
this.window = window;
}
public void handle(Event newest) {
System.out.println(newest);
events.addLast(newest);
if (events.size() == minimumGroupSize) {
Event oldest = events.peekFirst();
if (newest.getTimestamp() - oldest.getTimestamp() < window) {
System.out.println("Group starter: " + oldest);
}
events.removeFirst();
}
}
public static class Event {
private final long timestamp;
Event(long timestamp) {
this.timestamp = timestamp;
}
public long getTimestamp() {
return timestamp;
}
public String toString() {
return String.valueOf(timestamp);
}
}
public static void main(String[] args) {
EventMonitor monitor = new EventMonitor(5, 15);
feedEventData(monitor);
}
private static void feedEventData(EventMonitor monitor) {
long timestamp = 0;
for (int i = 0; i < 20; i++) {
long interval = 1 + (long) (Math.random() * 10);
timestamp = timestamp + interval;
monitor.handle(new Event(timestamp));
}
}
}
公共类事件监视器{
私有int最小组大小;
私人长窗;
专用链路