Java 合并多个事件流

Java 合并多个事件流,java,algorithm,events,Java,Algorithm,Events,假设我有N个数据事件流,我想将它们组合成一个,例如使用一些时间戳排序。假设EventStream定义为: class EventStream{ Event peek(); Event next(); } 现在我想取N个事件流,将它们封装在一个流中,这将强制执行排序。但是,我不想简单地遍历所有流并将它们添加到priorityQueue中——我不希望所有事件都在内存中,因为我会很快耗尽堆空间。我想要一种动态的方法,在这种方法中,每个下一个事件之后的组合流计算出下一个事件应该是什

假设我有N个数据事件流,我想将它们组合成一个,例如使用一些时间戳排序。假设EventStream定义为:

class EventStream{

    Event peek();

    Event next();
}

现在我想取N个事件流,将它们封装在一个流中,这将强制执行排序。但是,我不想简单地遍历所有流并将它们添加到priorityQueue中——我不希望所有事件都在内存中,因为我会很快耗尽堆空间。我想要一种动态的方法,在这种方法中,每个下一个事件之后的组合流计算出下一个事件应该是什么。我可以每次扫描N个流,找出下一个值,但是有更好的方法吗?

你的方法很好。除非N很大,否则它应该是可以的


如果N真的很大,您可以将每个流的第一个事件存储在一个排序集合中,与它来自的流相关联,并且每次从这个排序集合中删除一个项目时,您都可以从它来自的流中添加下一个项目。

您的方法很好。除非N很大,否则它应该是可以的


如果N真的很大,您可以将每个流的第一个事件存储在一个排序集合中,与它来自的流相关联,并且每次从该排序集合中删除一个项时,您可以从它来自的流中添加下一个流。

只需偷看流的头部,并且仅在需要时这样做,就可以避免缓存所有内容和在流上执行过多的查找。我建议您编写一个与此类似的MergedEventStream:

public class MergedEventStream implements EventStream {

    private ArrayList<EventStream> merged = new ArrayList<EventStream>();
    private int nextIndex = -1;

    public MergedEventStream(Collection<EventStream> toMerge) {
        merged.addAll(toMerge);
        findNext();
    }

    public Event peek() {
        if (nextIndex == -1 && findNext() == false) {
           throw new NoSuchElementException();
        } else {
           Event e = merged.get(nextIndex).peek();
           return e;
        }
    }

    public Event peek() {
        if (nextIndex == -1 && findNext() == false) {
           throw new NoSuchElementException();
        } else {
           Event e = merged.get(nextIndex).next();
           findNext();
           return e;
        }
    }

    /**
     * iterates over merged, and for each stream with an available event,
     * adds it to a sorted TreeMap<Event, Integer> (sorting by any event field; integer
     * is stream index in arrayList)
     * if set is not empty, returns 'true', and sets nextIndex to the stream index
     * otherwise, returns 'false', and sets nextIndex to -1
     */
    private boolean findNext() {
        // ...
    }
}

您可以将树状图作为实例属性保留,并仅刷新从中提取的流,从而在一定程度上提高效率。

您可以通过只查看流的头部并仅在需要时这样做来避免缓存所有内容和对流进行过多的查找。我建议您编写一个与此类似的MergedEventStream:

public class MergedEventStream implements EventStream {

    private ArrayList<EventStream> merged = new ArrayList<EventStream>();
    private int nextIndex = -1;

    public MergedEventStream(Collection<EventStream> toMerge) {
        merged.addAll(toMerge);
        findNext();
    }

    public Event peek() {
        if (nextIndex == -1 && findNext() == false) {
           throw new NoSuchElementException();
        } else {
           Event e = merged.get(nextIndex).peek();
           return e;
        }
    }

    public Event peek() {
        if (nextIndex == -1 && findNext() == false) {
           throw new NoSuchElementException();
        } else {
           Event e = merged.get(nextIndex).next();
           findNext();
           return e;
        }
    }

    /**
     * iterates over merged, and for each stream with an available event,
     * adds it to a sorted TreeMap<Event, Integer> (sorting by any event field; integer
     * is stream index in arrayList)
     * if set is not empty, returns 'true', and sets nextIndex to the stream index
     * otherwise, returns 'false', and sets nextIndex to -1
     */
    private boolean findNext() {
        // ...
    }
}

通过将树状图作为实例属性保留,并仅刷新从中提取的流,可以在一定程度上提高效率。

使用MinHeap存储每个事件流中的一个事件

下一次,从堆中弹出顶部事件,并显示最早时间的值

然后从从中检索事件的同一事件流中推入一个事件

因此,MinHeap中每个EventStream只有一个事件

您需要将对EventStream的引用与事件一起存储在MinHeap中

下一个实现将使用Olog n,其中“n”是事件流的数量


注意:预计EventStream的已排序事件。Next始终返回最早的事件。

使用MinHeap存储每个事件流中的一个事件

下一次,从堆中弹出顶部事件,并显示最早时间的值

然后从从中检索事件的同一事件流中推入一个事件

因此,MinHeap中每个EventStream只有一个事件

您需要将对EventStream的引用与事件一起存储在MinHeap中

下一个实现将使用Olog n,其中“n”是事件流的数量


注意:预计EventStream的已排序事件。Next总是返回最早的事件。

听起来像是你想要一个排序的堆而不排序。听起来像是你想要一个排序的堆而不排序。2是我建议的同一件事-你赢了我的一票2是我建议的同一件事-你赢了我的一票这不正是我在回答中建议的吗?这不正是我建议的吗我的回答中有什么建议?