Ayons cette classe C # (ce serait presque la même chose en 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;
}
}
Comme vous pouvez le voir, l'égalité de deux instances de MyClass
dépend A
uniquement de. Il peut donc y avoir deux instances égales, mais détenant différentes informations dans leur B
propriété.
Dans une bibliothèque de collection standard de nombreux langages (y compris C # et Java, bien sûr), il y a un Set
( HashSet
en C #), qui une collection, qui peut contenir au plus un élément de chaque ensemble d'instances égales.
On peut ajouter des éléments, supprimer des éléments et vérifier si l'ensemble contient un élément. Mais pourquoi est-il impossible d'obtenir un élément particulier de l'ensemble?
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
La seule façon de récupérer mon article est d'itérer sur toute la collection et de vérifier l'égalité de tous les articles. Cependant, cela prend du O(n)
temps au lieu de O(1)
!
Jusqu'à présent, je n'ai trouvé aucune langue qui prend en charge get à partir d'un ensemble. Tous les langages "courants" que je connais (Java, C #, Python, Scala, Haskell ...) semblent être conçus de la même manière: vous pouvez ajouter des éléments, mais vous ne pouvez pas les récupérer. Y a-t-il une bonne raison pour laquelle toutes ces langues ne prennent pas en charge quelque chose d'aussi simple et évidemment utile? Ils ne peuvent pas tout simplement se tromper, non? Y a-t-il des langues qui le prennent en charge? Peut-être que récupérer un élément particulier d'un ensemble est faux, mais pourquoi?
Il y a quelques questions liées au SO:
/programming/7283338/getting-an-element-from-a-set
/programming/7760364/how-to-retrieve-actual-item-from-hashsett
Set<E>
implémentations sont juste Map<E,Boolean>
à l'intérieur.
a == b
toujours vraie) au cas où this.A == null
. Le if (item == null || this.A == null || item.A == null)
test est "exagéré" et vérifie beaucoup, peut-être afin de créer artificiellement du code "de haute qualité". Je vois ce genre de "dépassement" et d'être trop correct tout le temps sur la révision du code.
std::set
prend en charge la récupération d'objets, donc tous les langages "courants" ne sont pas comme vous le décrivez.