Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么是字典;未订购;?_C#_.net_Dictionary_Base Class Library_Operator Precedence - Fatal编程技术网

C# 为什么是字典;未订购;?

C# 为什么是字典;未订购;?,c#,.net,dictionary,base-class-library,operator-precedence,C#,.net,Dictionary,Base Class Library,Operator Precedence,我读这篇文章是为了回答这里的许多问题。但这到底意味着什么 var test = new Dictionary<int, string>(); test.Add(0, "zero"); test.Add(1, "one"); test.Add(2, "two"); test.Add(3, "three"); Assert(test.ElementAt(2).Value == "two"); var test=newdictionary(); 测试。添加(0,“零”); 测试。添加(

我读这篇文章是为了回答这里的许多问题。但这到底意味着什么

var test = new Dictionary<int, string>();
test.Add(0, "zero");
test.Add(1, "one");
test.Add(2, "two");
test.Add(3, "three");

Assert(test.ElementAt(2).Value == "two");
var test=newdictionary();
测试。添加(0,“零”);
测试。添加(1,“一”);
测试。添加(2,“两”);
测试。添加(3,“三”);
断言(test.ElementAt(2.Value==“2”);
上面的代码似乎按预期工作。那么,词典以什么方式被认为是无序的呢?在什么情况下上述代码会失败

A
Dictionary
表示一个哈希表,在哈希表中没有顺序的概念

这本书很好地解释了这一点:

为便于枚举,每个项目 在字典中被视为 键值对结构 表示一个值及其键。这个 返回项目的顺序 没有定义


首先,我们不清楚这是插入顺序还是键顺序。例如,如果您编写以下内容,您希望得到什么结果:

var test = new Dictionary<int, string>();
test.Add(3, "three");
test.Add(2, "two");
test.Add(1, "one");
test.Add(0, "zero");

Console.WriteLine(test.ElementAt(0).Value);
var test=newdictionary();
测试。添加(3,“三”);
测试。添加(2,“两”);
测试。添加(1,“一”);
测试。添加(0,“零”);
Console.WriteLine(test.ElementAt(0.Value));
你期望“三”还是“零”

事实上,我认为当前的实现保留了插入顺序,只要您从不删除任何内容—但您不能依赖于此。这是一个实现细节,将来可能会发生变化

删除也会影响这一点。例如,您希望该计划的结果是什么

using System;
using System.Collections.Generic;

class Test
{ 
    static void Main() 
    {
        var test = new Dictionary<int, string>();
        test.Add(3, "three");
        test.Add(2, "two");
        test.Add(1, "one");
        test.Add(0, "zero");

        test.Remove(2);
        test.Add(5, "five");

        foreach (var pair in test)
        {
            Console.WriteLine(pair.Key);
        }
    }     
}
使用系统;
使用System.Collections.Generic;
课堂测试
{ 
静态void Main()
{
var test=新字典();
测试。添加(3,“三”);
测试。添加(2,“两”);
测试。添加(1,“一”);
测试。添加(0,“零”);
测试。移除(2);
测试。添加(5,“五”);
foreach(测试中的var对)
{
控制台写入线(配对键);
}
}     
}
实际上(在我的盒子上)是3,5,1,0。5的新条目使用了2以前使用的空条目。但这也不能保证

重新格式化(当字典的底层存储需要扩展时)可能会影响一些事情。。。各种各样的事情都会发生


不要将其视为有序集合。它不是为这个设计的。即使它现在正好工作,您也依赖于未记录的行为,这违背了类的目的。

顺序是不确定的

出于枚举的目的,字典中的每个项都被视为表示值及其键的KeyValuePair结构。返回项目的顺序未定义

可能是为了满足您的需要。

我不知道C#或任何.NET,但字典的一般概念是它是键值对的集合。
您不会像迭代列表或数组时那样按顺序访问字典。
您可以通过拥有一个键来访问,然后查找字典中是否有该键的值以及该值是什么。
在您的示例中,您发布了一个带有数字键的字典,这些数字键恰好是连续的,没有空格,并且按插入的升序排列。
但无论您以何种顺序插入键“2”的值,在查询键“2”时都会得到相同的值。
我不知道C#是否允许,我想是的,有数字以外的键类型,但在这种情况下,它是相同的,键上没有明确的顺序。

与现实生活中的字典进行类比可能会令人困惑,因为单词的键是按字母顺序排列的,因此我们可以更快地找到它们,但如果不是,字典无论如何都会起作用,因为单词“土豚”的定义将具有相同的含义,即使它位于“斑马”之后。另一方面,想想一本小说,改变页面的顺序没有任何意义,因为它们本质上是一个有序的集合。

这里有很多好的想法,但都是零散的,所以我将尝试创建一个答案,更好地展示它,即使问题已经得到解决

首先,字典没有保证的顺序,所以使用它只是快速查找键并找到相应的值,或者枚举所有键-值对,而不考虑顺序是什么

如果您想要订单,可以使用OrderedDictionary,但折衷是查找速度较慢,因此如果您不需要订单,就不要要求订单

字典(以及Java中的HashMap)使用哈希。无论您的桌子大小,这都是0(1)次。有序字典通常使用某种平衡树,即O(log2(n)),因此随着数据的增长,访问速度会变慢。要进行比较,对于一百万个元素,这大约是2^20,因此必须对一棵树进行20次查找,但对一个哈希映射进行1次查找。那要快得多

哈希是确定性的。非决定论意味着,当你第一次散列(5),下一次散列(5),你会得到一个不同的位置。那完全没有用

人们的意思是,如果向字典中添加内容,顺序会很复杂,并且在添加(或可能删除)元素时可能会发生更改。例如,假设哈希表中有500k个元素,而您有400k个值。当您再添加一个时,您就达到了临界阈值,因为它需要大约20%的空空间来提高效率,因此它会分配一个更大的表(例如,100万个条目)并重新散列所有值。现在他们都在不同的地方,比以前

如果你构建同一本词典两次(仔细阅读我的陈述,同样),你将得到相同的顺序。但正如乔恩正确地说的,不要指望它。太多的事情会使它变得不一样,甚至是最初分配的大小

这提出了一个极好的观点。调整hashmap的大小非常非常昂贵。这意味着您必须分配一个更大的表,并重新插入每个k
new Foo();
var f1 = new Foo(1);
var f2 = new Foo(1);
var test = new Dictionary<Foo, string>();
test.Add(f1, "zero");
var test = new Dictionary<Foo, string>();
test.Add(f2, "zero");
public SortedDictionary<string, Row> forecastMTX = new SortedDictionary<string, Row>();