HashSet.` This is an optimized set collection. It helps eliminates duplicate strings or elements in an array. It is a set that hashes its contents.`With HashSet,` we have a simple syntax for taking the union of elements in a set. This is performed in its constructor. More complex methods can be used on the HashSet. `Constructor `constructor`This program` contains a source array that contains several duplicated strings. It eliminates duplicate strings in the array. The program calls the HashSet constructor. `This internally calls the UnionWith method to eliminate the duplications. ToArray transforms the HashSet into a new array.`ToArray `toarray`Notes, above example.` The input array contains six strings (four unique). The string "cat" is repeated three times. The HashSet constructor eliminates the non-unique elements.`Notes, continued.` The HashSet constructor receives a single parameter, which must implement the IEnumerable<string> generic interface. The constructor takes the union of elements. `Generic Class `generic`String Literal `string-literal`The program displays string arrays onto the console or as single strings using the string.Join static method.`Static Method `static`Join receives the result of the ToArray extension method, which was invoked on the HashSet instance.`Join `string-join`Overlaps.` This method returns true or false. It tests to see if any of the HashSet's elements are contained in the IEnumerable argument's elements. Only one equal element is required. `IEnumerable `ienumerable`Next: `The element 3 is in the HashSet. This means Overlaps returns true for array2, but false for array3.`SymmetricExceptWith.` HashSet has advanced set logic. SymmetricExceptWith changes HashSet so that it contains only the elements in one or the other collection—not both. `This example shows the use of the var-keyword. This simplifies the syntax of the HashSet declaration statement.`Var `var`Dictionary.` Set logic can also be implemented by using a Dictionary instead of a HashSet. With a Dictionary you must specify a value type. This may lead to more confusing code. `The Dictionary code will have more lines, but performance would be similar. The hash lookup loops are equivalent.`Dictionary `dictionary`Allocations.` Using Dictionary and HashSet results in allocations on the managed heap. For small source inputs, the HashSet and Dictionary will be slower than simple nested loops. `But: `When the source input becomes large with thousands of elements, hashed collections are faster.`Dictionary Lookup Performance `dictionary-time`Benchmark.` Is there any performance benefit to using HashSet instead of Dictionary? In the C# language, a Dictionary with bool values can work as a set. `We test a HashSet(string) against a Dictionary(string, bool). We add strings as keys and see if those keys exist.`Notes, benchmark.` The Dictionary had slightly better performance in this test than did the HashSet. In most tests the Dictionary was faster. `Dictionary StringComparer Optimization `dictionary-stringcomparer`My guideline is that Dictionary should be used instead of HashSet in places where advanced HashSet functionality is not needed.`A summary.` HashSet can be applied to elegantly eliminate duplicates in an array. Its constructor takes a union of a collection that implements the IEnumerable generic interface.

VXY XPXO; X XPXO.LinqXSXDX; { VX$V{Y VVX{Input XT that cX9 three duplicate XLs. VVYXL[] XT1 = VV{X'Y"cat"Y,X'Y"dog"Y,X'Y"cat"Y,X'Y"leopard"Y,X'Y"tiger"Y,X'Y"cat"Y VV};Y VVX{X5 the XT. VVYX%XL.Join(Y","Y, XT1));Y VVX{Use HashSet constructorXlensure unique XLs. VVYvar hashXzXwYHashSet<XL>Y(XT1);Y VVX{CXHXlXT of XLs again. VVYXL[] XT2Xzhash.ToXU();Y VVX{X5 the XIing XT. VVYX%XL.Join(Y","Y, XT2)); V} } Y cat,dog,cat,leopard,tiger,cat cat,dog,leopard,tigerY XPXO; X XDX; { VX$V{ VVX}[] XT1Xz{ 1, 2, 3 }; VVX}[] XT2Xz{ 3, 4, 5 }; VVX}[] XT3Xz{ 9, 10, 11 }XSVVHashSet<X}> setXzXwHashSet<X}>(XT1); VVbool aXzset.YOverlapsY(XT2); VVbool bXzset.YOverlapsY(XT3);Y VVX{X5 XIs. VVYX%a); VVX%b); V} } Y True FalseY XPXO; X XPXO.LinqXSXDX; { VX$V{ VVchar[] XT1Xz{ 'a', 'b', 'c' }; VVchar[] XT2Xz{ 'b', 'c', 'd' }XSVVvar hashXzXwHashSet<char>(XT1); VVhash.YSymmetricExceptWithY(XT2);Y VVX{Xh char XT. VVYX%hash.ToXU()); V} } Y adY XPXO; X X! XDX; { Vconst Xs_maxXz10000000; VX$V{ VVvar hXzXwHashSet<XL>(XMComparer.Ordinal); VVvar dXzXwDX+<XL, bool>(XMComparer.Ordinal); VVvar aXzXwXL[] { "a", "b", "c", "d", "longer", "words", "also" }XSVVvar s1XzX-.XcNew(); VVXo(XsiXz0; i < _max; i++) VV{X'X7 (XL sXka)X'{X'Vh.Xns);X'Vh.CX9(s);X'} VV} VVs1X1; VVvar s2XzX-.XcNew(); VVXo(XsiXz0; i < _max; i++) VV{X'X7 (XL sXka)X'{X'Vd[s]Xztrue;X'Vd.CX9Key(s);X'} VV} VVs2X1; VVX%h.XW); VVX%d.XW)XSVVX%(X.(s1.X" * 1000000) /X'_max).ToXM("0.00 ns")); VVX%(X.(s2.X" * 1000000) /X'_max).ToXM("0.00 ns")); VVX4.Xx(); V} } YResultsY 7 7 Y529.99 nsYVHashSet Y517.05 nsYVDX+Y

eHashSet on duplicatesXOverlapscSymmetricExceptWith9tests HashSet performance