Lassen Sie uns diese C # -Klasse haben (in Java wäre es fast dasselbe)
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;
}
}
Wie Sie sehen können, ist die Gleichheit von zwei Instanzen von MyClass
hängt dieA
nur ab. Es kann also zwei Instanzen geben, die gleich sind, aber unterschiedliche Informationen in ihrer B
Eigenschaft enthalten.
In einer Standardsammlungsbibliothek mit vielen Sprachen (einschließlich C # und natürlich Java) gibt es eine Set
( HashSet
in C #), eine Sammlung, die höchstens ein Element aus jedem Satz gleicher Instanzen enthalten kann.
Man kann Gegenstände hinzufügen, Gegenstände entfernen und prüfen, ob das Set einen Gegenstand enthält. Aber warum ist es unmöglich, einen bestimmten Gegenstand aus dem Set zu bekommen?
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
Die einzige Möglichkeit, meinen Artikel abzurufen, besteht darin, die gesamte Sammlung zu durchlaufen und alle Artikel auf Gleichheit zu prüfen. Dies dauert jedochO(n)
Zeit statt O(1)
!
Ich habe noch keine Sprache gefunden, die unterstützt wird. Alle "gebräuchlichen" Sprachen, die ich kenne (Java, C #, Python, Scala, Haskell ...), scheinen auf dieselbe Weise gestaltet zu sein: Sie können Elemente hinzufügen, aber nicht abrufen. Gibt es einen guten Grund, warum all diese Sprachen etwas nicht unterstützen, das so einfach und offensichtlich nützlich ist? Sie können nicht einfach alle falsch sein, oder? Gibt es Sprachen, die dies unterstützen? Vielleicht ist es falsch, einen bestimmten Gegenstand aus einem Set zurückzuerhalten, aber warum?
Es gibt einige verwandte SO-Fragen:
/programming/7283338/getting-an-element-from-a-set
/programming/7760364/how-to-retrieve-actual-item-from-hashsett
Set<E>
Implementierungen nur Map<E,Boolean>
im Inneren.
a == b
immer wahr) für den Fall this.A == null
. Der if (item == null || this.A == null || item.A == null)
Test ist "übertrieben" und prüft zu viel, möglicherweise um künstlich "hochwertigen" Code zu erstellen. Ich sehe diese Art von "Überprüfung" und die ganze Zeit über die richtige Codeüberprüfung.
std::set
unterstützt das Abrufen von Objekten, daher sind nicht alle "allgemeinen" Sprachen so, wie Sie es beschreiben.