.net HashSet<T> 和 List<T> 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6391738/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between HashSet<T> and List<T>?
提问by pencilCake
Can you explain what is the difference between HashSet<T>and List<T>in .NET?
你能解释一下.NETHashSet<T>和List<T>.NET之间的区别吗?
Maybe you can explain with an example in what cases HashSet<T>should be preferred against List<T>?
也许你可以用一个例子来解释在什么情况下HashSet<T>应该优先考虑List<T>?
回答by BonyT
Unlike a List<> ...
不像 List<> ...
A HashSet is a List with no duplicate members.
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
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 doesn't implement IList only ICollection
You cannot use indices with a HashSet, only enumerators.
HashSet 是一个没有重复成员的列表。
由于 HashSet 被限制为仅包含唯一条目,因此内部结构针对搜索进行了优化(与列表相比) - 它要快得多
添加到 HashSet 返回一个布尔值 - 如果由于已存在于 Set 中而导致添加失败,则为 false
可以对集合执行数学集合操作:Union/Intersection/IsSubsetOf 等。
HashSet 不只实现 IList ICollection
您不能将索引与 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 的等效操作进行比较。写起来也更整洁!
回答by GorkemHalulu
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.Collections.Generic.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, SymmetricExceptWithetc.
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:
顺便说一下,顺序不保留在 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
回答by jason
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).
AHashSet<T>是一个旨在让您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).
AList<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>
也许你可以用一个例子来解释在什么情况下
HashSet<T>应该优先考虑List<T>
When you want to test containment in O(1).
当您想测试O(1).
回答by Waylon Flinn
Use a List<T>when you want to:
List<T>当你想使用 a时:
- 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:
Hashset<T>当你想使用 a时:
- 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).
如果您知道要查找的事物的名称,则 Lookup 是O(1)(即“哈希”部分)。它不像以前那样保持排序,List<T>并且您不能存储重复项(添加重复项无效,这是“设置”部分)。
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.
何时使用 a 的一个例子Hashset<T>是,如果您想确定在拼字游戏中玩的单词是否是英语(或其他语言)中的有效单词。如果您想构建一个供此类游戏的在线版本的所有实例使用的 Web 服务,那就更好了。
A List<T>would be a good data structure for creating the scoreboard to track player scores.
AList<T>将是一个很好的数据结构,用于创建记分板以跟踪玩家得分。
回答by dgvid
List is an ordered list. It is
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))
- Does not guarantee the order of the items within the set
- Has operations you would expect on a set, e.g., IntersectWith, IsProperSubsetOf, UnionWith.
- 可以阻止重复项(请参阅Add(T))
- 不保证集合内物品的顺序
- 具有您期望在集合上进行的操作,例如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 是更好的选择。
回答by Bob Vale
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.
HashSet 就像一个字典,项目本身既是键又是值,不能保证排序。
You would use a HashSet where you want to check that an object is in the collection
您将使用 HashSet 来检查对象是否在集合中
回答by therealmitchconnors
List is not necessarily unique, while hashset is, for one.
List 不一定是唯一的,而 hashset 是唯一的。
回答by Nathan Teague
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.
此外,如果使用 DataAnnotations 类,则可以在类属性上实现 Key 逻辑,并使用 HashSet 有效控制自然索引(集群或非集群),这在 List 实现中将非常困难。
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.
使用列表的一个强有力的选择是在视图模型上为多种媒介实现泛型,例如将类列表发送到 DropDownList 帮助程序的 MVC 视图,以及通过 WebApi 作为 JSON 构造发送。该列表允许典型的类集合逻辑,并为更像“接口”的方法保持灵活性,以将单个视图模型计算到不同的媒介。

