0

我想使用 System.Collections.Generic.Queue,但有一个区别:我希望 Queue.Peek 返回放入的最后一项而不是第一项。我仍然希望项目以相同的方式进入和退出。

我正在考虑使用 Queue.Last() 作为 Queue.Peek() 的替代品(我认为它与 Queue.First() 基本相同)但我想知道这是否意味着枚举器将逐字地枚举整个在到达最后一个元素之前排队。由于我的队列将非常大,这可能是一个问题。

编辑:

透视我正在尝试做的事情:假设我想逐分钟保存过去 20 年的股票价格数据库。这将是许多数据点。为了做到这一点,我想每分钟将最新价格排入队列,并在队列大小超过 20 年时将最早价格出列。但是,我还想要一种方便的方法来从队列中获取最新价格。我知道 Queue.Last(),它可以解决问题,但我只想知道它是否会非常低效。

4

3 回答 3

2

如果集合 implements IList<T>,则indexer 属性同时用于and First()Last()通常O(1),尽管不是必须的)。

否则,调用First()将只获取第一个元素(如果枚举器支持延迟执行,则立即退出),但调用Last()必须枚举整个集合

IQueue<T>不执行IList<T>

于 2015-05-05T16:09:28.000 回答
1

听起来您不想使用队列而是双端队列。

进行Last调用将创建一个Enumerator实例,该实例的私有内部类Queue<T>将用于枚举从头到尾,因为Queue<T>没有实现IList<T>接口。因此Last将是一个 O(n) 操作。

于 2015-05-05T16:13:00.413 回答
0

你是对的 - 对于队列, Last 将遍历每个元素。Enumerable.Last 有 ILists 的快捷方式,但没有 Queues 的快捷方式。

听起来您只想要一个记住最后添加的项目的队列。您可以在 Queue 周围创建一个简单的包装器,可以有效地返回最后一项......

public class StockQueue<T>
{
    private readonly queue; 

    public StockQueue(Queue<T> source)
    {
        this.queue = source;
    }

    public T LastAdded {get; private set;}

    public Enqueue(T item)
    {
        // Remember the last item added
        this.lastAdded = item;
        this.queue.Enqueue(item);
    }

    // Implement any other Queue members you need, passing the calls through
    // to the internal queue.
    public T Dequeue()
    {
        return this.queue.Dequeue();
    }

    public T Peek()
    {
        return this.queue.Peek();
    }
}
于 2015-05-05T16:16:26.733 回答