DQ DQbJA%{U:PPU{=U'PU{jPyqPU{NjUPPUyS{=MU'PUDQ JA%zUyzUyzUybzyqzUyUyU{=M''DQ DQbJA%UyUybyqUU{aU'SDQ !JAiy%yqPOyq-POyqPby,`wiy@Ppv:3y,`wiy@Ppy:3']']b'0#O'0#O5u-aAaAEDBrBDfEBXBWB| 6888649664VZBCBCBZC 776VCB 76VCBWBW F8ZC-

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 XX; XXX.LinqXXX { VXV{Y VVXInput X that cX three duplicate Xs. VVYX[] X1 = VV{ VVVY"cat"Y, VVVY"dog"Y, VVVY"cat"Y, VVVY"leopard"Y, VVVY"tiger"Y, VVVY"cat"Y VV};Y VVXX the X. VVYXX.Join(Y","Y, X1));Y VVXUse HashSet constructorXensure unique Xs. VVYvar hashXXYHashSet<X>Y(X1);Y VVXCXXX of Xs again. VVYX[] X2Xhash.ToX();Y VVXX the Xing X. VVYXX.Join(Y","Y, X2)); V} } Y cat,dog,cat,leopard,tiger,cat cat,dog,leopard,tigerY XX; X XX { VXV{ VVX[] X1X{ 1, 2, 3 }; VVX[] X2X{ 3, 4, 5 }; VVX[] X3X{ 9, 10, 11 }XVVHashSet<X> setXXHashSet<X>(X1); VVbool aXset.YOverlapsY(X2); VVbool bXset.YOverlapsY(X3);Y VVXX Xs. VVYXa); VVXb); V} } Y True FalseY XX; XXX.LinqXXX { VXV{ VVchar[] X1X{ 'a', 'b', 'c' }; VVchar[] X2X{ 'b', 'c', 'd' }XVVvar hashXXHashSet<char>(X1); VVhash.YSymmetricExceptWithY(X2);Y VVXX char X. VVYXhash.ToX()); V} } Y adY XX; XX XX { Vconst X_maxX10000000; VXV{ VVvar hXXHashSet<X>(XComparer.Ordinal); VVvar dXXDX<X, bool>(XComparer.Ordinal); VVvar aXXX[] { "a", "b", "c", "d", "longer", "words", "also" }XVVvar s1XX.XNew(); VVX(XiX0; i < _max; i++) VV{ VVVX (X sXa) VVV{ VVVVh.Xs); VVVVh.CX(s); VVV} VV} VVs1X; VVvar s2XX.XNew(); VVX(XiX0; i < _max; i++) VV{ VVVX (X sXa) VVV{ VVVVd[s]Xtrue; VVVVd.CXKey(s); VVV} VV} VVs2X; VVXh.X); VVXd.X)XVVX(X(s1.X * 1000000) / VVV_max).ToX("0.00 ns")); VVX(X(s2.X * 1000000) / VVV_max).ToX("0.00 ns")); VVX.X(); V} } YResultsY 7 7 Y529.99 nsYVHashSet Y517.05 nsYVDXY

$eXc9HashSet on duplicatesOverlapsSymmetricExceptWithtests HashSet performance