Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't System...Stack<T> implemented as a Linked List?

I was looking through my code and I found a couple of extension methods that I wrote in order to remove items from a System.Collections.Generic.Stack. I was curious, so I looked at the source of Stack with Reflector and I can see that they implemented it as an array instead of a linked list and I'm just wondering why? With a linked list there would be no need to resize an internal array...

Here are my extensions, any criticisms or suggestions are welcome. Thanks.

public static Stack<T> Remove<T>(this Stack<T> stack, T item)
{
    Stack<T> newStack = new Stack<T>();

    EqualityComparer<T> eqc = EqualityComparer<T>.Default;

    foreach( T newItem in stack.Reverse() )
    {
        if( !eqc.Equals(newItem, item) )
        {
            newStack.Push(newItem);
        }
    }

    return newStack;
}
/// <summary>
/// Returns a new Stack{T} with one or more items removed, based on the given predicate.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="stack"></param>
/// <param name="fnRemove"></param>
/// <returns>The new stack.</returns>
/// <remarks>
/// We have to turn tricks in order to save the LIFO order of the pool
/// since there is no built-in remove method since they implement a Stack internally
/// as an array instead of a linked list. Maybe they have a good reason, I don't know...
/// 
/// So, to fix this I'm just using a LINQ extension method to enumerate in reverse.
/// </remarks>
public static Stack<T> RemoveWhere<T>(this Stack<T> stack, Predicate<T> fnRemove)
{
    Stack<T> newStack = new Stack<T>();

    foreach( T newItem in stack.Reverse() )
    {
        /// Check using the caller's method.
        if( fnRemove(newItem) )
        {
            /// It's not allowed in the new stack.
            continue;
        }
        newStack.Push(newItem);
    }

    return newStack;
}
like image 407
Wayne Bloss Avatar asked Dec 01 '22 12:12

Wayne Bloss


1 Answers

A LIFO queue (a stack) is typically most efficient with an array, because you are pushing items onto the end of the array and pulling items off the same end of the array. So an array works well, without the memory and allocation overhead of a linked list. The cost of making and resizing an array is offset by not needing to create and garbage collect the list item wrapper objects.

like image 121
Lawrence Dol Avatar answered Dec 05 '22 08:12

Lawrence Dol