HashSet和List有什么区别?

时间:2021-07-25 21:29:04

Can you explain what is the difference between HashSet<T> and List<T> in .NET?

你能解释一下HashSet 和List 在。net中的区别吗?

Maybe you can explain with an example in what cases HashSet<T> should be preferred against List<T> ?

也许你可以用一个例子来说明在什么情况下HashSet 应该优先于List ?

Thanks.

谢谢。

8 个解决方案

#1


184  

Unlike a List<> ...

与列表< >…

  1. A HashSet is a List with no duplicate members.

    HashSet是一个没有重复成员的列表。

  2. Because a HashSet is constrained to contain only unique entries, the internal structure is optimised for searching (compared with a list) - it is considerably faster

    因为HashSet被限制为只包含唯一的条目,所以内部结构被优化为搜索(与列表相比)——它要快得多

  3. Adding to a HashSet returns a boolean - false if addition fails due to already existing in Set .) Can perform mathematical set operations against a Set: Union/Intersection/IsSubsetOf etc.

    添加到HashSet返回一个布尔- false,如果添加失败,因为已经在Set中存在。可以对集合执行数学集合操作:Union/ crossroads /IsSubsetOf等。

  4. HashSet doesn't implement IList only ICollection

    HashSet并不是只实现IList查询

  5. You cannot use indices with a HashSet, only enumerators.

    不能使用带HashSet的索引,只能使用枚举数。

The main reason to use a HashSet would be if you are interested in performing Set operations.

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

Given 2 sets: hashSet1 and hashSet2

给定2组:hashSet1和hashSet2。

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

flies in comparison with an equivalent operation using LINQ. It's also neater to write!

与使用LINQ的等效操作进行比较。写起来也更整洁!

#2


48  

A HashSet<T> is a class designed to give you O(1) lookup for containment (i.e., does this collection contain a particular object, and tell me the answer fast).

HashSet 是一个用于为包含(例如)提供O(1)查找的类。,这个集合是否包含一个特定对象,并快速告诉我答案。

A List<T> is a class designed to give you a collection with O(1) random access than can grow dynamically (think dynamic array). You can test containment in O(n) time (unless the list is sorted, then you can do a binary search in O(log n) time).

List 是一个类,其目的是为您提供一个具有O(1)随机访问的集合,而不是动态增长(比如动态数组)。您可以在O(n)时间内测试包含(除非列表已排序,那么您可以在O(log n)时间内进行二进制搜索)。

Maybe you can explain with an example in what cases HashSet<T> should be prefered against List<T>

也许你可以用一个例子来说明在什么情况下HashSet 应该优先于List

When you want to test containment in O(1).

当你想在O(1)中测试容器时。

#3


44  

To be more precise lets demonstrate with examples,

更准确地说,让我们用例子来演示,

You can not use HashSet like in the following example.

您不能像下面的示例那样使用HashSet。

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

hashSet1[i] would produce an error:

hashSet1[i]会产生一个错误:

Cannot apply indexing with [] to an expression of type 'System.Collections.Generic.HashSet'

不能将带[]的索引应用到' system . collection . general . hashset '类型的表达式中

You can use foreach statement:

你可以使用foreach语句:

foreach (var item in hashSet1)
    Console.WriteLine(item);

You can not add duplicated items to HashSet while List allows you to do this and while you are adding an item to HashSet, you can check wheter it contains the item or not.

您不能将重复项添加到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 has some useful functions like IntersectWith, UnionWith, IsProperSubsetOf, ExceptWith, SymmetricExceptWith etc.

HashSet有一些有用的函数,如IntersectWith、UnionWith、IsProperSubsetOf、ExceptWith、SymmetricExceptWith等。

IsProperSubsetOf:

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:

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:

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 :

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 :

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

By the way, the order is not preserved in HashSets. In the example, we added element "2" last but it is in the second order:

顺便说一下,顺序并没有保存在散列集中。在这个例子中,我们最后添加了元素“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

#4


18  

Use a List<T> when you want to:

当你想要使用列表 时:

  • Store a collection of items in a certain order.
  • 以一定的顺序存储项目的集合。

If you know the index of the item you want (rather than the value of the item itself) retrieval is O(1). If you don't know the index, finding the item takes more time, O(n) for an unsorted collection.

如果您知道您想要的项的索引(而不是项本身的值),那么检索就是O(1)。如果您不知道索引,那么查找条目将花费更多的时间,O(n)用于未排序的集合。

Use a Hashset<T> when you want to:

当你想:

  • Quickly find out if a certain object is contained in a collection.
  • 快速查找某个对象是否包含在集合中。

If you know the name of the thing you want to find, Lookup is O(1) (that's the 'Hash' part). It doesn't maintain an ordering like the List<T> does and you can't store duplicates (adding a duplicate has no effect, that's the 'Set' part).

如果您知道要查找的对象的名称,那么查找就是O(1)(这是“哈希”部分)。它不像列表 那样维护排序,也不能存储重复项(添加重复项没有效果,这是“Set”部分)。

An example of when to use a Hashset<T> would be if you want to find out if a word played in a game of Scrabble is a valid word in English (or other language). Even better would be if you wanted to build a web service to be used by all instances of an online version of such a game.

如果您想知道在拼字游戏中玩的单词在英语(或其他语言)中是否是一个有效的单词,那么在什么时候使用Hashset 就是一个例子。如果您希望构建一个web服务供此类游戏的在线版本的所有实例使用,那就更好了。

A List<T> would be a good data structure for creating the scoreboard to track player scores.

一个列表 是一个很好的数据结构,用来创建记分板来跟踪玩家的分数。

#5


13  

List is an ordered list. It is

List是一个有序的List。它是

  • accessed by an integer index
  • 由整数索引访问。
  • can contain duplicates
  • 可以包含重复
  • has a predictable order
  • 有一个可预测的订单

HashSet is a set. It:

HashSet是一个集合。

  • Can block duplicate items (see Add(T))
  • 可以阻塞重复的项(参见Add(T)))
  • Does not guarantee the order of the items within the set
  • 不保证集合内物品的顺序
  • Has operations you would expect on a set, e.g., IntersectWith, IsProperSubsetOf, UnionWith.
  • 具有您希望在集合上执行的操作,例如,IntersectWith、IsProperSubsetOf、UnionWith。

List is more appropriate when you want to access you collection as though it were like an array to which you could append, insert and remove items. HashSet is a better choice if you want to treat your collection like a "bag" of items in which order is not important or when you want to compare it with other sets using the operations such as IntersectWith or UnionWith.

当您希望访问集合时,List更合适,就好像您可以向它添加、插入和删除项一样。如果您希望将您的集合视为不重要的项目的“包”,或者希望使用IntersectWith或UnionWith等操作将其与其他集合进行比较,那么HashSet是更好的选择。

#6


3  

A List is an ordered collection of objects of Type T that unlike an array you can add and remove entries.

列表是类型为T的有序对象集合,与可以添加和删除条目的数组不同。

You would use a list where you want to reference the members in the order you stored them and you are accessing them by an position rather than the item itself.

您将使用一个列表,在该列表中,您希望按照存储它们的顺序引用成员,而您是通过一个位置而不是项目本身访问它们。

A HashSet is like a dictionary that the item itself is the key as well as the value, the ordering is not guaranteed.

哈希集就像字典一样,条目本身既是键又是值,排序没有保证。

You would use a HashSet where you want to check that an object is in the collection

您将使用HashSet来检查集合中的对象

#7


2  

List is not necessarily unique, while hashset is, for one.

列表不一定是唯一的,而hashset是。

#8


0  

If you decide to apply these data structures to actual usage in data-driven development, a HashSet is VERY helpful in testing replication against data adapter sources, for data cleansing and migration.

如果您决定将这些数据结构应用于数据驱动开发中的实际使用,HashSet对于测试针对数据源的复制、数据清理和迁移非常有用。

Also, if using the DataAnnotations Class, one can implement Key logic on class properties and effectively control a Natural Index (clustered or not) with a HashSet, where this would be very difficult in a List implementation.

此外,如果使用dataannotation类,则可以在类属性上实现键逻辑,并有效地使用HashSet控制自然索引(集群化或不集群化),这在列表实现中非常困难。

A strong option for using a list is to implement generics for multiple mediums on a View Model, such as sending a list of classes to a MVC View for a DropDownList Helper, and also for sending as a JSON construct via WebApi. The list allows typical class collection logic, and keeps flexibility for a more "Interface" like approach to computing a single view model to different mediums.

使用列表的一个强大选项是为视图模型上的多个介质实现泛型,例如将类列表发送到MVC视图中作为下拉列表助手,以及通过WebApi作为JSON结构发送。列表允许典型的类集合逻辑,并保持灵活性,以一种更“接口”的方式计算不同媒介的单个视图模型。

#1


184  

Unlike a List<> ...

与列表< >…

  1. A HashSet is a List with no duplicate members.

    HashSet是一个没有重复成员的列表。

  2. Because a HashSet is constrained to contain only unique entries, the internal structure is optimised for searching (compared with a list) - it is considerably faster

    因为HashSet被限制为只包含唯一的条目,所以内部结构被优化为搜索(与列表相比)——它要快得多

  3. Adding to a HashSet returns a boolean - false if addition fails due to already existing in Set .) Can perform mathematical set operations against a Set: Union/Intersection/IsSubsetOf etc.

    添加到HashSet返回一个布尔- false,如果添加失败,因为已经在Set中存在。可以对集合执行数学集合操作:Union/ crossroads /IsSubsetOf等。

  4. HashSet doesn't implement IList only ICollection

    HashSet并不是只实现IList查询

  5. You cannot use indices with a HashSet, only enumerators.

    不能使用带HashSet的索引,只能使用枚举数。

The main reason to use a HashSet would be if you are interested in performing Set operations.

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

Given 2 sets: hashSet1 and hashSet2

给定2组:hashSet1和hashSet2。

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

flies in comparison with an equivalent operation using LINQ. It's also neater to write!

与使用LINQ的等效操作进行比较。写起来也更整洁!

#2


48  

A HashSet<T> is a class designed to give you O(1) lookup for containment (i.e., does this collection contain a particular object, and tell me the answer fast).

HashSet 是一个用于为包含(例如)提供O(1)查找的类。,这个集合是否包含一个特定对象,并快速告诉我答案。

A List<T> is a class designed to give you a collection with O(1) random access than can grow dynamically (think dynamic array). You can test containment in O(n) time (unless the list is sorted, then you can do a binary search in O(log n) time).

List 是一个类,其目的是为您提供一个具有O(1)随机访问的集合,而不是动态增长(比如动态数组)。您可以在O(n)时间内测试包含(除非列表已排序,那么您可以在O(log n)时间内进行二进制搜索)。

Maybe you can explain with an example in what cases HashSet<T> should be prefered against List<T>

也许你可以用一个例子来说明在什么情况下HashSet 应该优先于List

When you want to test containment in O(1).

当你想在O(1)中测试容器时。

#3


44  

To be more precise lets demonstrate with examples,

更准确地说,让我们用例子来演示,

You can not use HashSet like in the following example.

您不能像下面的示例那样使用HashSet。

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

hashSet1[i] would produce an error:

hashSet1[i]会产生一个错误:

Cannot apply indexing with [] to an expression of type 'System.Collections.Generic.HashSet'

不能将带[]的索引应用到' system . collection . general . hashset '类型的表达式中

You can use foreach statement:

你可以使用foreach语句:

foreach (var item in hashSet1)
    Console.WriteLine(item);

You can not add duplicated items to HashSet while List allows you to do this and while you are adding an item to HashSet, you can check wheter it contains the item or not.

您不能将重复项添加到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 has some useful functions like IntersectWith, UnionWith, IsProperSubsetOf, ExceptWith, SymmetricExceptWith etc.

HashSet有一些有用的函数,如IntersectWith、UnionWith、IsProperSubsetOf、ExceptWith、SymmetricExceptWith等。

IsProperSubsetOf:

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:

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:

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 :

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 :

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

By the way, the order is not preserved in HashSets. In the example, we added element "2" last but it is in the second order:

顺便说一下,顺序并没有保存在散列集中。在这个例子中,我们最后添加了元素“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

#4


18  

Use a List<T> when you want to:

当你想要使用列表 时:

  • Store a collection of items in a certain order.
  • 以一定的顺序存储项目的集合。

If you know the index of the item you want (rather than the value of the item itself) retrieval is O(1). If you don't know the index, finding the item takes more time, O(n) for an unsorted collection.

如果您知道您想要的项的索引(而不是项本身的值),那么检索就是O(1)。如果您不知道索引,那么查找条目将花费更多的时间,O(n)用于未排序的集合。

Use a Hashset<T> when you want to:

当你想:

  • Quickly find out if a certain object is contained in a collection.
  • 快速查找某个对象是否包含在集合中。

If you know the name of the thing you want to find, Lookup is O(1) (that's the 'Hash' part). It doesn't maintain an ordering like the List<T> does and you can't store duplicates (adding a duplicate has no effect, that's the 'Set' part).

如果您知道要查找的对象的名称,那么查找就是O(1)(这是“哈希”部分)。它不像列表 那样维护排序,也不能存储重复项(添加重复项没有效果,这是“Set”部分)。

An example of when to use a Hashset<T> would be if you want to find out if a word played in a game of Scrabble is a valid word in English (or other language). Even better would be if you wanted to build a web service to be used by all instances of an online version of such a game.

如果您想知道在拼字游戏中玩的单词在英语(或其他语言)中是否是一个有效的单词,那么在什么时候使用Hashset 就是一个例子。如果您希望构建一个web服务供此类游戏的在线版本的所有实例使用,那就更好了。

A List<T> would be a good data structure for creating the scoreboard to track player scores.

一个列表 是一个很好的数据结构,用来创建记分板来跟踪玩家的分数。

#5


13  

List is an ordered list. It is

List是一个有序的List。它是

  • accessed by an integer index
  • 由整数索引访问。
  • can contain duplicates
  • 可以包含重复
  • has a predictable order
  • 有一个可预测的订单

HashSet is a set. It:

HashSet是一个集合。

  • Can block duplicate items (see Add(T))
  • 可以阻塞重复的项(参见Add(T)))
  • Does not guarantee the order of the items within the set
  • 不保证集合内物品的顺序
  • Has operations you would expect on a set, e.g., IntersectWith, IsProperSubsetOf, UnionWith.
  • 具有您希望在集合上执行的操作,例如,IntersectWith、IsProperSubsetOf、UnionWith。

List is more appropriate when you want to access you collection as though it were like an array to which you could append, insert and remove items. HashSet is a better choice if you want to treat your collection like a "bag" of items in which order is not important or when you want to compare it with other sets using the operations such as IntersectWith or UnionWith.

当您希望访问集合时,List更合适,就好像您可以向它添加、插入和删除项一样。如果您希望将您的集合视为不重要的项目的“包”,或者希望使用IntersectWith或UnionWith等操作将其与其他集合进行比较,那么HashSet是更好的选择。

#6


3  

A List is an ordered collection of objects of Type T that unlike an array you can add and remove entries.

列表是类型为T的有序对象集合,与可以添加和删除条目的数组不同。

You would use a list where you want to reference the members in the order you stored them and you are accessing them by an position rather than the item itself.

您将使用一个列表,在该列表中,您希望按照存储它们的顺序引用成员,而您是通过一个位置而不是项目本身访问它们。

A HashSet is like a dictionary that the item itself is the key as well as the value, the ordering is not guaranteed.

哈希集就像字典一样,条目本身既是键又是值,排序没有保证。

You would use a HashSet where you want to check that an object is in the collection

您将使用HashSet来检查集合中的对象

#7


2  

List is not necessarily unique, while hashset is, for one.

列表不一定是唯一的,而hashset是。

#8


0  

If you decide to apply these data structures to actual usage in data-driven development, a HashSet is VERY helpful in testing replication against data adapter sources, for data cleansing and migration.

如果您决定将这些数据结构应用于数据驱动开发中的实际使用,HashSet对于测试针对数据源的复制、数据清理和迁移非常有用。

Also, if using the DataAnnotations Class, one can implement Key logic on class properties and effectively control a Natural Index (clustered or not) with a HashSet, where this would be very difficult in a List implementation.

此外,如果使用dataannotation类,则可以在类属性上实现键逻辑,并有效地使用HashSet控制自然索引(集群化或不集群化),这在列表实现中非常困难。

A strong option for using a list is to implement generics for multiple mediums on a View Model, such as sending a list of classes to a MVC View for a DropDownList Helper, and also for sending as a JSON construct via WebApi. The list allows typical class collection logic, and keeps flexibility for a more "Interface" like approach to computing a single view model to different mediums.

使用列表的一个强大选项是为视图模型上的多个介质实现泛型,例如将类列表发送到MVC视图中作为下拉列表助手,以及通过WebApi作为JSON结构发送。列表允许典型的类集合逻辑,并保持灵活性,以一种更“接口”的方式计算不同媒介的单个视图模型。