实现自定义泛型列表/队列/堆栈组合的有效方式(An efficient way to impleme

2019-09-22 16:09发布

我发现不止一个场合泛型集合必须在一个时间点和在另一个时间堆栈或队列视为列表。 对于我目前正在开发一个应用程序,它没有意义的,使用三个不同的对象。

我能想到的最简单的解决方案是实现队列/出列/按键/在标准列表流行/窥视功能。 也(未包括在下面的代码),接口约束施加于T允许类来维护每个列表,队列,堆的位置/顺序索引。

public class List<T>:
    System.Collections.Generic.List<T>
{
    private object SyncRoot = new object();

    public void Enqueue (T item)
    {
        lock (this.SyncRoot)
        {
            this.Add(item);
        }
    }

    public T Dequeue ()
    {
        T item = default(T);

        lock (this.SyncRoot)
        {
            if (this.Count > 0)
            {
                item = this [0];
                this.RemoveAt(0);
            }
        }

        return (item);
    }

    public void Push (T item)
    {
        lock (this.SyncRoot)
        {
            this.Add(item);
        }
    }

    public T Pop ()
    {
        T item = default(T);

        lock (this.SyncRoot)
        {
            if (this.Count > 0)
            {
                item = this [this.Count - 1];
                this.RemoveAt(this.Count - 1);
            }
        }

        return (item);
    }

    public T PeekQueue ()
    {
        T item = default(T);

        lock (this.SyncRoot)
        {
            if (this.Count > 0)
            {
                item = this [0];
            }
        }

        return (item);
    }

    public T PeekStack ()
    {
        T item = default(T);

        lock (this.SyncRoot)
        {
            if (this.Count > 0)
            {
                item = this [this.Count - 1];
            }
        }

        return (item);
    }
}
  • 由于这是一个粗略的,在即时实现,我不知道要寻找什么角落的情况下出了那么将不胜感激指针或链接到任何现有的这样的实现。
  • 其次,我怀疑在非常大名单的性能。 是从列表比使用LinkedList的说大型列表很好地继承了决定。 在我的情况下,添加/删除项目比枚举列表更优先。

Answer 1:

下面是如何acomplish与扩展方法类似的操作... http://weblogs.asp.net/bsimser/archive/2011/01/13/generic-pop-and-push-for-list-lt-t-gt的.aspx

一般流行,推动名单

这里有一个小片段我用来扩展一个泛型列表类具有相似的capabilites的Stack类。

Stack类是伟大的,但它在System.Object的生活在自己的世界。 那岂不是很高兴有一个列表,可以这样做? 下面的代码:

public static class ExtensionMethods    
{ 
    public static T Pop<T>(this List<T> theList)    
    {              
        var local = theList[theList.Count - 1];    
        theList.RemoveAt(theList.Count - 1);    
        return local;   
     }

     public static void Push<T>(this List<T> theList, T item)   
     {   
        theList.Add(item);   
     }   
}

这是一个简单的扩展,但我发现它很有用,希望你会呢! 请享用。

也扩展方法的链接http://msdn.microsoft.com/en-us/library/bb383977.aspx



Answer 2:

我猜你必须使用数组作为内部数据存储,它是如何在.NET列表和其他仿制药来实现。 例如,出列代码效率低下,因为在itnernal数组所有元素的无用应对的,而不是开始索引的移动。 人们可以在ILSpy C#反编译看:

// System.Collections.Generic.List<T>
/// <summary>Removes the element at the specified index of the <see cref="T:System.Collections.Generic.List`1" />.</summary>
/// <param name="index">The zero-based index of the element to remove.</param>
/// <exception cref="T:System.ArgumentOutOfRangeException">
///   <paramref name="index" /> is less than 0.-or-<paramref name="index" /> is equal to or greater than <see cref="P:System.Collections.Generic.List`1.Count" />.</exception>
public void RemoveAt(int index)
{
    if (index >= this._size)
    {
        ThrowHelper.ThrowArgumentOutOfRangeException();
    }
    this._size--;
    if (index < this._size)
    {
        Array.Copy(this._items, index + 1, this._items, index, this._size - index);
    }
    this._items[this._size] = default(T);
    this._version++;
}

其他功能可提高过一点点。

此外,我注意到,.NET堆栈通用实现速度很慢,比List泛型的实现。 我想这是因为分配新建分配FY的默认值,同时提取,不像目录栈的最后一个元素:

// System.Collections.Generic.Stack<T>
/// <summary>Removes and returns the object at the top of the <see cref="T:System.Collections.Generic.Stack`1" />.</summary>
/// <returns>The object removed from the top of the <see cref="T:System.Collections.Generic.Stack`1" />.</returns>
/// <exception cref="T:System.InvalidOperationException">The <see cref="T:System.Collections.Generic.Stack`1" /> is empty.</exception>
public T Pop()
{
    if (this._size == 0)
    {
        ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyStack);
    }
    this._version++;
    T result = this._array[--this._size];
    this._array[this._size] = default(T);
    return result;
}


文章来源: An efficient way to implement a custom generic list/queue/stack combination