3

I don't understand why there isn't a native function to do this. Suppose that I create the following class:

public class Student {
     public string Name {get; set;}
     public override int GetHashCode() {
         return(Name.GetHashCode());
     }
}

Afterwards, I create a HashSet containing a number of students. Now I want to get a student from the HashSet using his name, which is also the hash code used, without enumeration. Is this possible? If it is, how would I accomplish this? Since the name of the student is used as the hash code, this should be possible with an O(1) operation, right?

7
  • Use HashSet.Contains(). It is amortized O(1). Commented Apr 15, 2014 at 19:23
  • 1
    Use Dictionary<string,Student> and you can get the value as myDictionary["name"] Commented Apr 15, 2014 at 19:26
  • @Siriam I suppose that would work, but it would create consistency problems. What if the key of the dictionary is not the same as the name of the object? If there's no other workaround I suppose I'll have to settle with this solution. Thanks! Commented Apr 15, 2014 at 19:28
  • 1
    @OrestisP. I don't understand. Why do you imagine key is not same as name? In the end you're going to use right? So you need to make sure key is Name. Commented Apr 15, 2014 at 19:37
  • 1
    Obligatory Eric Lippert link: blogs.msdn.com/b/ericlippert/archive/2011/02/28/… Commented Apr 15, 2014 at 20:14

2 Answers 2

5

A hashcode is not a unique identifier. Different objects may have the same hashcode. The only requirement for hashcodes is that objects that are considered equal have the same hashcode.

If you need O(1) retrieval of an item based on a key, use a Dictionary<TKey, TValue>, not a HashSet<T>.

Sign up to request clarification or add additional context in comments.

11 Comments

A hashcode is indeed an identifier. In fact, I can check for the existence of an item in my HashSet<T> by comparing hash codes...
A KeyedCollection would be better than a Dictionary, due to the fact that the key depends on a property of the value.
@DavidHaney a hashcode does not - and cannot - uniquely identify an item.
@DavidHaney, I edited my answer to say "unique identifier". Happy now ? :)
@OrestisP., that's why using the name as the key is a very bad idea; your students should have an identifier (integer, Guid, or whatever you want) that will never change.
|
3

Instead of using a HashSet (or a Dictionary) to store your students use a KeyedCollection instead.

public class StudentCollection : KeyedCollection<string, Student>
{
    protected override string GetKeyForItem(Student item)
    {
        return student.Name;
    }
}

This will let you do lookups by name quickly just like a Dictionary but you don't need to manually pair up the name with the key when you are inserting. But be aware, no two students can have the same name or you will get a error (just the same as if you had a Dictionary and used two students of the same name).

3 Comments

Not an array of arrays, actually. IIRC, it's an array of linked lists (or something similar to linked lists, anyway).
I have greatly simplified my answer, if you would like to learn more about how a HashSet works, look at the revision history.
This seems to be exactly what I'm looking for! Going to test it now and will probably pick this answer if it's as good as it seems!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.