简体   繁体   中英

Discrepancies between output of Dictionary<int, string> and Queue<KeyValuePair<int, string>> in C#

Can anyone help me understand why the output of the two for loops below produce different outputs?

They to my eye are the same, however the original Dictionary object's for loop outputs all 9 of its members, but the Queue objects for loop outputs just the first 5.

void test()
{
        Dictionary<int, string> d = new Dictionary<int, string>();

        d.Add(0, "http://example.com/1.html");
        d.Add(1, "http://example.com/2.html");
        d.Add(2, "http://example.com/3.html");
        d.Add(3, "http://example.com/4.html");
        d.Add(4, "http://example.com/5.html");
        d.Add(5, "http://example.com/6.html");
        d.Add(6, "http://example.com/7.html");
        d.Add(7, "http://example.com/8.html");
        d.Add(8, "http://example.com/9.html");

        Queue<KeyValuePair<int, string>> requestQueue = new Queue<KeyValuePair<int, string>>();

        // build queue
        foreach (KeyValuePair<int, string> dictionaryListItem in d)
        {
            requestQueue.Enqueue(dictionaryListItem);
            Console.WriteLine(dictionaryListItem.Value);
        }

        Console.WriteLine("          ");

        for (int i = 0; i < requestQueue.Count; i++)
        {
            Console.WriteLine(requestQueue.Peek().Value);
            requestQueue.Dequeue();
        }
}

You need to save count before the loop:

var count = requestQueue.Count;
for (int i = 0; i < count; i++)
{
    Console.WriteLine(requestQueue.Peek().Value);
    requestQueue.Dequeue();
}

The reason is that it is evaluated at each iteration of the for loop:

At the start of the first iteration, requestQueue.Count is 9, i is 0 .
2nd iteration: requestQueue.Count is 8, i is 1 .
3rd iteration: requestQueue.Count is 7, i is 2 .
4th iteration: requestQueue.Count is 6, i is 3 .
5th iteration: requestQueue.Count is 5, i is 4 .
6th iteration: requestQueue.Count is 4, i is 5 . --> Exit loop.

Note: The Count of the queue is reduced with each iteration because Queue.Dequeue removes the first item in the queue and returns it to the caller.

You probably want to use this while-loop instead which is more meaningful here:

while (requestQueue.Count > 0)
{
    Console.WriteLine(requestQueue.Peek().Value);
    requestQueue.Dequeue();
}

The problem with your for-loop is that Queue.Dequeue removes the first item which also reduces the Count property. That's why it stops "part-way".

The loop variable i is still increasing whereas Count is decreasing.

Because you're changing the amount of items in requestQueue every time you call requestQueue.Dequeue(). Instead store the value of count in a local and loop with that local as the upper limit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM