HashSet<T>
您能解释一下 .NET和List<T>
.NET之间的区别吗?
也许你可以用一个例子来解释在哪些情况下HashSet<T>
应该优先考虑List<T>
?
HashSet<T>
您能解释一下 .NET和List<T>
.NET之间的区别吗?
也许你可以用一个例子来解释在哪些情况下HashSet<T>
应该优先考虑List<T>
?
不像 List<> ...
HashSet 是一个没有重复成员的列表。
因为 HashSet 被限制为仅包含唯一条目,所以内部结构针对搜索进行了优化(与列表相比) - 它要快得多
添加到 HashSet 会返回一个布尔值 - 如果由于 Set 中已经存在而添加失败,则返回 false
可以对集合执行数学集合操作:Union/Intersection/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 的等效操作相比。写起来也更整洁!
更准确地说,让我们用例子来演示,
您不能像以下示例中那样使用 HashSet。
HashSet<string> hashSet1 = new HashSet<string>(){"1","2","3"};
for (int i = 0; i < hashSet1.Count; i++)
Console.WriteLine(hashSet1[i]);
hashSet1[i]
会产生错误:
无法使用 [] 将索引应用于“System.Collections.Generic.HashSet”类型的表达式
您可以使用 foreach 语句:
foreach (var item in hashSet1)
Console.WriteLine(item);
您不能将重复的项目添加到 HashSet,而 List 允许您这样做,并且当您将项目添加到 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
AHashSet<T>
是一个旨在让您O(1)
查找包含的类(即,此集合是否包含特定对象,并快速告诉我答案)。
AList<T>
是一个类,旨在为您提供一个O(1)
随机访问的集合,而不是动态增长(想想动态数组)。您可以及时测试遏制O(n)
(除非列表已排序,否则您可以及时进行二进制搜索O(log n)
)。
也许你可以用一个例子来解释在哪些情况下
HashSet<T>
应该优先考虑List<T>
当您想在O(1)
.
当List<T>
您想要:
如果你知道你想要的项目的索引(而不是项目本身的值)检索是O(1)
. 如果您不知道索引,则O(n)
对于未排序的集合,查找该项目需要更多时间。
当Hashset<T>
您想要:
如果您知道要查找的事物的名称,则 Lookup 是O(1)
(即“哈希”部分)。它不像那样保持顺序,List<T>
并且您不能存储重复项(添加重复项没有效果,这就是“设置”部分)。
何时使用 a 的一个例子是,Hashset<T>
如果您想查明在拼字游戏中玩的单词是否是英语(或其他语言)中的有效单词。如果您想构建一个供此类游戏的在线版本的所有实例使用的 Web 服务,那就更好了。
AList<T>
将是一个很好的数据结构,用于创建记分牌以跟踪玩家得分。
List 是一个有序列表。这是
HashSet 是一个集合。它:
当您想要访问您的集合时,List 更合适,就好像它就像一个您可以追加、插入和删除项目的数组一样。如果您想将您的集合视为顺序不重要的“袋子”项目,或者当您想使用 IntersectWith 或 UnionWith 等操作将其与其他集合进行比较时,HashSet 是一个更好的选择。
List 不一定是唯一的,而 hashset 是唯一的。
List 是类型 T 对象的有序集合,与数组不同,您可以添加和删除条目。
您将使用一个列表,您希望按照存储它们的顺序在其中引用成员,并且您通过位置而不是项目本身来访问它们。
HashSet 就像一个字典,项目本身既是键也是值,不能保证顺序。
您将使用 HashSet 来检查对象是否在集合中
如果您决定将这些数据结构应用到数据驱动开发中的实际使用中,那么 HashSet 在测试针对数据适配器源的复制、数据清理和迁移方面非常有帮助。
此外,如果使用 DataAnnotations 类,可以在类属性上实现 Key 逻辑,并使用 HashSet 有效地控制自然索引(集群或非集群),这在 List 实现中是非常困难的。
使用列表的一个强大选项是在视图模型上实现多种媒体的泛型,例如将类列表发送到 DropDownList 助手的 MVC 视图,以及通过 WebApi 作为 JSON 构造发送。该列表允许典型的类集合逻辑,并为更类似于“接口”的方法保持灵活性,以将单个视图模型计算到不同的介质。