HashSet <T>和List <T>有什么区别?

pen*_*ake 151 .net list hashset difference

你能解释一下HashSet<T>List<T>.NET 之间有什么区别吗?

也许你可以用一个例子来解释在什么情况下HashSet<T>应该首选List<T>

谢谢.

Bon*_*nyT 200

与List <>不同......

  1. HashSet是一个没有重复成员的List.

  2. 因为HashSet被限制为仅包含唯一条目,所以内部结构针对搜索进行了优化(与列表相比) - 它的速度要快得多

  3. 添加到HashSet会返回一个布尔值 - 如果由于Set中已经存在而导致添加失败,则返回false.)可以对Set:Union/Intersection/IsSubsetOf等执行数学集合运算.

  4. HashSet不实现仅IList ICollection

  5. 您不能将索引与HashSet一起使用,只能使用枚举器.

如果您对执行Set操作感兴趣,使用HashSet的主要原因是.

给定2组:hashSet1和hashSet2

 //returns a list of distinct items in both sets
 HashSet set3 = set1.Union( set2 );
Run Code Online (Sandbox Code Playgroud)

与使用LINQ的等效操作相比较苍蝇.写起来也更整洁!

  • 实际上,我更喜欢答案,指出HashSets适合您可以将您的收藏视为"包裹物品"的情况.集合操作不像围堵检查那么频繁.在任何时候你有一组独特的项目(例如代码)并且你需要检查包含,HashSet是很方便的. (12认同)
  • +1"for"使用HashedSet的主要原因是,如果您对执行Set操作感兴趣." (2认同)

jas*_*son 51

A HashSet<T>是一个专门用于O(1)查找包含的类(即,此集合是否包含特定对象,并快速告诉我答案).

A List<T>是一个专门为您提供O(1)随机访问而不是动态增长的集合的类(想想动态数组).您可以及时测试包含O(n)(除非列表已排序,然后您可以及时进行二进制搜索O(log n)).

也许你可以用一个例子来解释HashSet<T>应该优先考虑的情况List<T>

当你想测试遏制时O(1).


Gor*_*ulu 50

为了更精确,让我们举例说明,

您不能像以下示例中那样使用HashSet.

HashSet<string> hashSet1 = new HashSet<string>(){"1","2","3"};
for (int i = 0; i < hashSet1.Count; i++)
    Console.WriteLine(hashSet1[i]);
Run Code Online (Sandbox Code Playgroud)

hashSet1[i] 会产生错误:

无法将带有[]的索引应用于"System.Collections.Generic.HashSet"类型的表达式

您可以使用foreach语句:

foreach (var item in hashSet1)
    Console.WriteLine(item);
Run Code Online (Sandbox Code Playgroud)

您不能将重复项添加到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'");
Run Code Online (Sandbox Code Playgroud)

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.");
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

顺便说一下,订单不会保留在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
Run Code Online (Sandbox Code Playgroud)

  • +1用于说明性示例.帮助我快速理解HashSet操作! (5认同)
  • 例如+1.初学者将更容易掌握. (3认同)

Way*_*inn 20

使用List<T>时间你想:

  • 按特定顺序存储项目集合.

如果你知道你想要的项目的索引(而不是项目本身的值)检索O(1).如果您不知道索引,则查找该项目会花费更多时间O(n)来处理未分类的集合.

使用Hashset<T>时间你想:

  • 快速查明集合中是否包含某个对象.

如果您知道要查找的事物的名称,则查找O(1)(即"哈希"部分).它没有保持像这样的排序List<T>,你不能存储重复(添加副本没有效果,这是'设置'部分).

Hashset<T>如果你想知道在Scrabble游戏中播放的单词是否是英语(或其他语言)中的有效单词,那么何时使用a的一个例子就是.如果您想构建一个Web服务,以供这种游戏的在线版本的所有实例使用,那就更好了.

A List<T>将是用于创建记分板以跟踪玩家得分的良好数据结构.


dgv*_*vid 15

列表是一个有序列表.它是

  • 由整数索引访问
  • 可以包含重复项
  • 有一个可预测的顺序

HashSet是一个集合.它:

  • 可以阻止重复的项目(请参阅添加(T))
  • 不保证集合中项目的顺序
  • 在集合上有您期望的操作,例如,IntersectWith,IsProperSubsetOf,UnionWith.

当您想要访问集合时,列表更合适,就像它可以追加,插入和删除项目的数组一样.如果您希望将您的集合视为"包"中的顺序不重要的项目,或者您希望使用IntersectWith或UnionWith等操作将其与其他集进行比较,则HashSet是更好的选择.