Using HashSet in .NET to allow unique values only

Hashsets allow you to add unique values into a collection. So if you have a rule that no two identical objects are added to a collection then a Set is a good choice.

Initialisation:

HashSet<int> integerSet = new HashSet<int>();

Add new items:

integerSet.Add(2);
integerSet.Add(3);

There’s no direct access available with an index parameter, like [2]. There’s no particular order to the items inserted to a Set. You’ll never know where the items end up and which one is the first in the list.

You can simply iterate through the values like this:

foreach (int value in integerSet)
{
}

If you try to add an integer that already exists then it will ignored. The Add method has a boolean return value. It will return false if the item you’re trying to add already exists in the collection and true otherwise.

You can easily build the intersection of two sets:

HashSet<int> integerSet1 = new HashSet<int>(){1, 2, 3};
HashSet<int> integerSet2 = new HashSet<int>(){2, 3, 4};

integerSet1.IntersectWith(integerSet2);

This operation will only keep those items in integerSet1 that were available in both sets, i.e. the intersection of the two sets: 2 and 3.

Building a union is equally easy:

integerSet1.UnionWith(integerSet2);

…resulting in integerSet1 = 1,2,3,4.

SymmetricExceptWith returns those items that are found in set 1 and set 2 but not both:

integerSet1.SymmetricExceptWith(integerSet2);

Result: 1,4.

If you want to store objects, such as Customer, Product, etc. then you need to take some extra care. Sets have no idea when two object are considered equal. By default the following operation will add both objects:

HashSet<Product> productSet = new HashSet<Product>();
productSet.Add(new Product() { Name = "A" });
productSet.Add(new Product() { Name = "A" });

These are two different objects, they point to two different locations in the memory heap.

One way to solve this is that object will implement the IEquatable interface and override the GetHashCode method:

public class Product : IEquatable<Product>
{
	public string Name { get; set; }

	public override int GetHashCode()
	{
		return Name.GetHashCode();
	}

	public bool Equals(Product other)
	{
		return this.Name.Equals(other.Name);
	}
}

This will prevent adding two equal objects to be added to the Set – provided that they should be considered equal of course.

LIFO data collection in .NET: Stack of T

If you need a data collection in .NET where you are forced to handle the objects in a last-in-first-out manner then you can use the Stack of T object: the last object added will be the first to come out. A typical scenario is a deck of cards: you pick the first card from the top, i.e. the one that was added last.

To initialise:

Stack&lt;Card&gt; stackOfCards = new Stack&lt;Card&gt;();

To add items:

stackOfCards.Push(new Card(ace));
stackOfCards.Push(new Card(ten));

To get the most recently added object from the stack:

Card next = stackOfCards.Pop();

The Pop() method will also remove the item from the collection. So the next time you call Pop() you’ll get the item added before the most recently added one.

Just like with a Queue of T you cannot directly reference an object in the stack collection by some index, e.g. [3].

The Peek() method will let you view the next item on the stack but it won’t be removed from the collection:

Card next = stackOfCards.Peek();

You can test for the absence of an item with Contains:

bool contains = stackOfCards.Contains(ace);

If you absolutely need to access the items directly then convert the stack into an array:

Card[] cardArray = stackOfCards.AsArray();

This will copy the items in the stack but leave the stack itself intact.

FIFO data structure in .NET: Queue of T

If you need a generic collection where you are forced to handle the elements on a first come first served basis then Queue will be your friend. There’s no Insert, Add or Delete method and you cannot access just any particular element by some index, like [2]. This data structure is most applicable in First-in-first-out – FIFO – scenarios.

To initialise:

Queue<Client> clientsQueueingInShop = new Queue<Client>();

To add objects:

clientsQueueingInShop.Enqueue(new Client {Name = "Nice person"});
clientsQueueingInShop.Enqueue(new Client {Name = "My friend"});
clientsQueueingInShop.Enqueue(new Client {Name = "My neighbour"});

To retrieve the first object in the queue:

Client nextUp = clientsQueueingInShop.Dequeue();

This will not only get the first client – “Nice person” – in the queue but also remove it from the collection. So that the next time you call Dequeue() it will return “My friend”.

You can look at the next item in the queue by calling the Peek() method. It doesn’t remove the object from the collection, in other words it will return the same object on subsequent calls:

Client nextUp = clientsQueueingInShop.Peek();

You can query the queue to see if it contains a particular element:

bool contains = clientsQueueingInShop.Contains(myFavouriteClient);

You will need to make sure of course that the objects are comparable in the queue.

In case you absolutely must access an object in the queue by some index one option is to convert the queue to an array:

Client[] clientArrays = clientsQueueingInShop.ToArray();

This will create a copy of the queue as an array, the original queue remains intact.

ultimatemindsettoday

A great WordPress.com site

Elliot Balynn's Blog

A directory of wonderful thoughts

HarsH ReaLiTy

A Good Blog is Hard to Find

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: