【问题标题】:Discrepancies between output of Dictionary<int, string> and Queue<KeyValuePair<int, string>> in C#C# 中 Dictionary<int, string> 和 Queue<KeyValuePair<int, string>> 的输出之间的差异
【发布时间】:2013-02-12 14:13:24
【问题描述】:

谁能帮我理解为什么下面两个for loops 的输出会产生不同的输出?

在我看来它们是相同的,但是原始 Dictionary 对象的 for loop 输出其所有 9 个成员,但 Queue 对象 for loop 仅输出前 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();
        }
}

【问题讨论】:

    标签: c# dictionary queue


    【解决方案1】:

    你需要在循环之前保存计数:

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

    原因是在 for 循环的每次迭代中都会对其进行评估:

    在第一次迭代开始时,requestQueue.Count 是 9,i0
    第二次迭代:requestQueue.Count 是 8,i1
    第三次迭代:requestQueue.Count 是 7,i2
    第 4 次迭代:requestQueue.Count 是 6,i3
    第 5 次迭代:requestQueue.Count 是 5,i4
    第 6 次迭代:requestQueue.Count 是 4,i5。 --> 退出循环。

    注意:队列的Count 会随着每次迭代而减少,因为Queue.Dequeue 会删除队列中的第一项并将其返回给调用者。

    【讨论】:

    • 正确。谢谢。为什么需要这样做?会认为 requestQueue.Count 会持有正确的 val 吗?
    • @RodgersandHammertime:它确实拥有正确的值。请再次检查我的答案。您确实意识到Dequeue 会从队列中删除该项目?
    【解决方案2】:

    您可能想改用这个while-loop,这在这里更有意义:

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

    您的for-loop 的问题是Queue.Dequeue 删除了第一项,这也减少了Count 属性。这就是它“中途”停止的原因。

    循环变量i 仍在增加,而Count 正在减少。

    【讨论】:

    • @Rodgers 和 Hammertime:如果由于某种原因需要索引,也可以将 for 循环更改为 for (int i = 0; requestQueue.Count &gt; 0; i++)
    【解决方案3】:

    因为每次调用 requestQueue.Dequeue() 时都会更改 requestQueue 中的项目数量。而是将 count 的值存储在本地并以该本地作为上限进行循环。

    【讨论】:

      猜你喜欢
      • 2011-03-05
      • 1970-01-01
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多