Let's have this C# class (it would be almost the same in Java)public class MyClass {   public string A {get; set;}   public string B {get; set;}   public override bool Equals(object obj) {        var item = obj as MyClass;        if (item == null || this.A == null || item.A == null)        {            return false;        }        return this.A.equals(item.A);   }   public override int GetHashCode() {        return A != null ? A.GetHashCode() : 0;   }}As you can see, equality of two instances of MyClass depends on A only. So there can be two instances that are equal, but holding different piece of information in their B property.In a standard collection library of many languages (including C# and Java, of course) there is a Set (HashSet in C#), which a collection, which can hold at most one item from each set of equal instances.One can add items, remove items and check if the set contains an item. But why is it impossible to get a particular item from the set?HashSet<MyClass> mset = new HashSet<MyClass>();mset.Add(new MyClass {A = Hello, B = Bye});//I can do thisif (mset.Contains(new MyClass {A = Hello, B = See you})) {    //something}//But I cannot do this, because Get does not exist!!!MyClass item = mset.Get(new MyClass {A = Hello, B = See you});Console.WriteLine(item.B); //should print ByeThe only way to retrieve my item is to iterate over the whole collection and check all items for equality. However, this takes O(n) time instead of O(1)!I haven't found any language that supports get from a set so far. All common languages I know (Java, C#, Python, Scala, Haskell...) seem to be designed in the same way: you can add items, but you cannot retrieve them. Is there any good reason why all these languages do not support something that easy and obviously useful? They cannot be just all wrong, right? Are there any languages that do support it? Maybe retreiving a particular item from a set is wrong, but why?There are a few related SO questions:https://stackoverflow.com/questions/7283338/getting-an-element-from-a-sethttps://stackoverflow.com/questions/7760364/how-to-retrieve-actual-item-from-hashsett
Should Set have a Get method?
java;c#;design;language design;collections
The problem here isn't that HashSet lacks a Get method, it's that your code makes no sense from the perspective of the HashSet type. That Get method is effectively, get me this value , please, to which the .NET framework folk would sensibly reply, eh? You already have that value <confused face />.If you want to store items and then retrieve them based on matching another slightly different value, then use Dictionary<String, MyClass> as you can then do:var mset = new Dictionary<String, MyClass>();mset.Add(Hello, new MyClass {A = Hello, B = Bye});var item = mset[Hello];Console.WriteLine(item.B); // will print ByeThe information of equality leaks from the encapsulated class. If I wanted to change the set of properties involved in Equals, I would have to change the code outside MyClass... Well yes, but that's because MyClass runs amok with the principle of least astonishment (POLA). With that equality functionality encapsulated, it is completely reasonable to assume that the following code is valid:HashSet<MyClass> mset = new HashSet<MyClass>();mset.Add(new MyClass {A = Hello, B = Bye});if (mset.Contains(new MyClass {A = Hello, B = See you})) {    // this code is unreachable.}To prevent this, MyClass needs to be clearly documented as to its odd form of equality. Having done that, it's no longer encapsulated and  changing how that equality works would break the open/closed principle. Ergo, it shouldn't change and therefore Dictionary<String, MyClass> is a good solution for this odd requirement.