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 this
if (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 Bye
The 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-set
https://stackoverflow.com/questions/7760364/how-to-retrieve-actual-item-from-hashsett
std::set
supports object retrieval, so not all "common" languages are like you describe.Set<E>
implementations are justMap<E,Boolean>
on the inside.a == b
always true) in casethis.A == null
. Theif (item == null || this.A == null || item.A == null)
test is "overdone" and checks to much, possibly in order to create artificially "high-quality" code. I see this kind of "overchecking" and being overly correct all the time on Code Review.