你能解释一下.NET中的HashSet<T>
和List<T>
之间有什么区别?HashSet <T>和List <T>有什么区别?
也许你可以在什么情况下应该HashSet<T>
对List<T>
首选的例子解释一下吗?
谢谢。
你能解释一下.NET中的HashSet<T>
和List<T>
之间有什么区别?HashSet <T>和List <T>有什么区别?
也许你可以在什么情况下应该HashSet<T>
对List<T>
首选的例子解释一下吗?
谢谢。
不像名单<> ...
HashSet的是一个没有重复成员列表。
因为一个HashSet被限制为只包含唯一入口,内部结构搜索(使用列表进行比较)进行了优化 - 这是相当快
添加到HashSet返回一个布尔 - 假的,如果除了失败是由于现有的设置 )可以针对一组执行数学组操作:联盟/交集/ IsSubsetOf等
HashSet中没有实现IList只有ICollection的
你不能在HashSet中使用索引,只能使用枚举器。
使用HashSet的主要原因是如果您有兴趣执行Set操作。
鉴于2套:hashSet1和hashSet2
//returns a list of distinct items in both sets
HashSet set3 = set1.Union(set2);
苍蝇与使用LINQ的等效操作的比较。写起来也很贴心!
列表不一定是唯一的,而哈希集是一个。
A HashSet<T>
是一个类,旨在为您提供O(1)
查找遏制(即该集合是否包含特定对象,并快速告诉我答案)。
一个List<T>
是设计,让您的集合与O(1)
随机存取比可以动态增长(想想动态数组)的类。您可以在O(n)
时间内测试遏制(除非列表已排序,那么您可以在O(log n)
时间执行二进制搜索)。
Maybe you can explain with an example in what cases
HashSet<T>
should be prefered againstList<T>
当您想测试遏制在O(1)
。
除O(log n)列表排序外,毕竟,它比在未排序的列表中查找更快。 – Andrei
列表是类型T的对象的有序集合,与数组不同,您可以添加和删除条目。
您将使用一个列表,您想按照您存储它们的顺序引用成员,并且您正在通过位置而不是项目本身访问它们。
HashSet就像一个字典,该项目本身是关键以及价值,排序不保证。
要检查的对象是集合
为了澄清,如果其他人乍看之下读错了 - 列表'保持一个顺序(即添加事物),但不会自动分类项目。你必须调用'.Sort'或者使用'SortedList'。 – drzaus
使用List<T>
中,当你想你可以使用一个HashSet来:
如果您知道所需物品的索引(而不是物品本身的值),则检索为O(1)
。如果您不知道索引,找到该项目需要更多时间,O(n)
用于未分类的集合。
使用Hashset<T>
当你想:如果某个对象包含在集合中
如果你知道你想要找的东西的名字,查找是O(1)
(这是“哈希”部分)。它不会保留像List<T>
那样的顺序,并且您不能存储重复项(添加副本不起作用,这是“设置”部分)。
例如,何时使用Hashset<T>
可能是因为您想了解拼字游戏中的单词是否是英语(或其他语言)中的有效单词。如果你想构建一个网络服务供所有这种游戏的在线版本使用,那么更好的办法是。
A List<T>
将是一个很好的数据结构,用于创建记分牌来跟踪玩家的得分。
列表是有序列表。它是
HashSet的是一组。它:
当您想要访问您的集合时,列表更加合适,就像它可以像您可以添加,插入和删除项目的数组一样。如果你想把你的集合看作是一个“包”,其顺序不重要,或者当你想用其他集合比较它时,HashSet是一个更好的选择,使用诸如IntersectWith或UnionWith之类的操作。
为了更加精确让有例子表明,
不能在下面的例子中使用的HashSet等。
HashSet<string> hashSet1 = new HashSet<string>(){"1","2","3"};
for (int i = 0; i < hashSet1.Count; i++)
Console.WriteLine(hashSet1[i]);
hashSet1[i]
会产生一个错误:
Cannot apply indexing with [] to an expression of type 'System.Collections.Generic.HashSet'
您可以使用foreach语句:
foreach (var item in hashSet1)
Console.WriteLine(item);
,而列表可以让你做你无法复制的项目添加到HashSet的这个和 当你正在添加一个项目到HashSet时,你可以检查它是否包含该项目与否。
HashSet<string> hashSet1 = new HashSet<string>(){"1","2","3"};
if (hashSet1.Add("1"))
Console.WriteLine("'1' is successfully added to hashSet1!");
else
Console.WriteLine("'1' could not be added to hashSet1, because it contains '1'");
HashSet的具有像IntersectWith
,UnionWith
,IsProperSubsetOf
,ExceptWith
,一些有用的功能SymmetricExceptWith
等
IsProperSubsetOf
:
HashSet<string> hashSet1 = new HashSet<string>() { "1", "2", "3", "4" };
HashSet<string> hashSet2 = new HashSet<string>() { "2", "4", "6", "8" };
HashSet<string> hashSet3 = new HashSet<string>() { "1", "2", "3", "4", "5" };
if (hashSet1.IsProperSubsetOf(hashSet3))
Console.WriteLine("hashSet3 contains all elements of hashSet1.");
if (!hashSet1.IsProperSubsetOf(hashSet2))
Console.WriteLine("hashSet2 does not contains all elements of hashSet1.");
UnionWith
:
HashSet<string> hashSet1 = new HashSet<string>() { "3", "4" };
HashSet<string> hashSet2 = new HashSet<string>() { "2", "4", "6", "8" };
hashSet1.UnionWith(hashSet2); //hashSet1 -> 3, 2, 4, 6, 8
IntersectWith
:
HashSet<string> hashSet1 = new HashSet<string>() { "3", "4", "8" };
HashSet<string> hashSet2 = new HashSet<string>() { "2", "4", "6", "8" }
hashSet1.IntersectWith(hashSet2);//hashSet1 -> 4, 8
ExceptWith
:
HashSet<string> hashSet1 = new HashSet<string>() { "1", "2", "3", "5", "6" };
HashSet<string> hashSet2 = new HashSet<string>() { "1", "2", "3", "4" };
hashSet1.ExceptWith(hashSet2);//hashSet1 -> 5, 6
SymmetricExceptWith
:
HashSet<string> hashSet1 = new HashSet<string>() { "1", "2", "3", "5", "6" };
HashSet<string> hashSet2 = new HashSet<string>() { "1", "2", "3", "4" };
hashSet1.SymmetricExceptWith(hashSet2);//hashSet1 -> 4, 5, 6
顺便说一句,订单不会保留HashSets。在这个例子中,我们添加元素“2”最后,但它是在第二顺序:
HashSet<string> hashSet1 = new HashSet<string>() { "3", "4", "8" };
hashSet1.Add("1"); // 3, 4, 8, 1
hashSet1.Remove("4"); // 3, 8, 1
hashSet1.Add("2"); // 3, 2 ,8, 1
如果您决定将这些数据结构在数据驱动的发展实际使用情况,HashSet的是在测试非常有帮助针对数据适配器源的复制,用于数据清理和迁移。另外,如果使用DataAnnotations类,则可以实现类属性的Key逻辑,并有效控制具有HashSet的自然索引(聚簇或不聚类),这在List实现中非常困难。
使用列表的一个强有力的选择是在视图模型上实现多种媒介的泛型,比如向DropDownList Helper的MVC视图发送一个类的列表,以及通过WebApi发送为JSON构造。该列表允许典型的类集合逻辑,并且为更多的“接口”类似的方法保持灵活性,以将单个视图模型计算到不同的介质。
关于该主题的一些阅读:[C#/ .NET基础知识:选择正确的收集类](http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the -right-collection-class.aspx) –
我建议你参考http://en.wikipedia.org/wiki/Hash_table和http://en.wikipedia.org/wiki/Dynamic_array上的维基百科文章。 – mquander
有关性能相关内容,请参见[hashset-vs-list-performance](http:// stackoverflow。com/questions/150750/hashset-vs-list-performance) – nawfal