Diamo questa classe C # (sarebbe quasi la stessa 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;
}
}
Come puoi vedere, l'uguaglianza di due casi MyClass
dipende A
solo da. Quindi ci possono essere due casi uguali, ma che contengono diverse informazioni nella loro B
proprietà.
In una libreria di raccolta standard di molte lingue (incluso C # e Java, ovviamente) c'è un Set
( HashSet
in C #), che è una raccolta, che può contenere al massimo un elemento da ogni set di istanze uguali.
Si possono aggiungere oggetti, rimuovere oggetti e verificare se il set contiene un oggetto. Ma perché è impossibile ottenere un determinato oggetto dal 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
L'unico modo per recuperare il mio articolo è di scorrere su tutta la raccolta e verificare la parità di tutti gli elementi. Tuttavia, questo richiede O(n)
tempo invece di O(1)
!
Finora non ho trovato alcuna lingua che supporti ottenere da un set. Tutte le lingue "comuni" che conosco (Java, C #, Python, Scala, Haskell ...) sembrano progettate allo stesso modo: è possibile aggiungere elementi, ma non è possibile recuperarli. C'è qualche buona ragione per cui tutte queste lingue non supportano qualcosa di così facile e ovviamente utile? Non possono essere solo tutti sbagliati, giusto? Ci sono lingue che lo supportano? Forse ritirare un determinato oggetto da un set è sbagliato, ma perché?
Esistono alcune domande SO correlate:
/programming/7283338/getting-an-element-from-a-set
/programming/7760364/how-to-retrieve-actual-item-from-hashsett
Set<E>
implementazioni sono solo Map<E,Boolean>
all'interno.
a == b
sempre vera) nel caso this.A == null
. Il if (item == null || this.A == null || item.A == null)
test è "esagerato" e controlla molto, probabilmente al fine di creare un codice artificialmente di "alta qualità". Vedo questo tipo di "controllo eccessivo" e di essere sempre eccessivamente corretto nella revisione del codice.
std::set
supporta il recupero di oggetti, quindi non tutti i linguaggi "comuni" sono come li descrivi.