Hadi bu C # sınıfına sahip olalım (Java'da neredeyse aynı olurdu)
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;
}
}
Görebildiğiniz gibi, iki vakanın eşitliği yalnızca MyClass
bağlıdır A
. Dolayısıyla eşit olan ancak B
mülklerinde farklı bilgiler taşıyan iki örnek olabilir .
Pek çok dilin (tabii ki C # ve Java dahil) standart bir koleksiyon kütüphanesinde, her bir eşit örnek kümesinden en fazla bir öğeyi tutabilen bir koleksiyonun Set
( HashSet
C # içinde) olduğu görülmektedir.
Bir öğe ekleyebilir, öğeleri kaldırabilir ve setin bir öğe içerip içermediğini kontrol edebilirsiniz. Ancak belirli bir öğeyi setten almak neden imkansız?
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
Maddemi almanın tek yolu, tüm koleksiyon boyunca yinelemektir ve tüm öğeleri eşitlik açısından kontrol etmektir. Ancak, O(n)
bunun yerine zaman alır O(1)
!
Şimdiye kadarki bir setten almayı destekleyen bir dil bulamadım. Tanıdığım tüm "ortak" diller (Java, C #, Python, Scala, Haskell ...) aynı şekilde tasarlanmış gibi görünüyor: öğeler ekleyebilirsiniz, ancak bunları alamazsınız. Tüm bu dillerin kolay ve bariz bir şekilde faydalı bir şeyi desteklememesinin iyi bir nedeni var mı? Hepsi yanlış olamaz, değil mi? Bunu destekleyen diller var mı? Belki belirli bir öğeyi setten tekrar almak yanlıştır, fakat neden?
SO ile ilgili birkaç soru var:
/programming/7283338/getting-an-element-from-a-set
/programming/7760364/how-to-retrieve-actual-item-from-hashsett
Set<E>
uygulama yalnızca Map<E,Boolean>
içeridedir.
a == b
durumda refleksivite ( her zaman doğru) kırılır this.A == null
. if (item == null || this.A == null || item.A == null)
Test muhtemelen yapay "kaliteli" kod yaratmak için, çok için "abartılı" ve çekler olduğunu. Bu tür bir "overchecking" ve Kod İncelemesinde her zaman aşırı dürüst olduğumu görüyorum.
std::set
nesne alımını destekler, yani "ortak" dillerin hepsi tanımladığınız gibi değildir.