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 MyClassdipende Asolo da. Quindi ci possono essere due casi uguali, ma che contengono diverse informazioni nella loro Bproprietà.
In una libreria di raccolta standard di molte lingue (incluso C # e Java, ovviamente) c'è un Set( HashSetin 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 == bsempre 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::setsupporta il recupero di oggetti, quindi non tutti i linguaggi "comuni" sono come li descrivi.