Mari kita buat kelas C # ini (akan hampir sama di Jawa)
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;
}
}
Seperti yang Anda lihat, persamaan dua contoh hanya MyClass
bergantung pada A
. Jadi bisa ada dua contoh yang sama, tetapi memegang informasi yang berbeda di B
properti mereka .
Di perpustakaan koleksi standar banyak bahasa (termasuk C # dan Java, tentu saja) ada Set
( HashSet
dalam C #), yang koleksi, yang dapat menampung paling banyak satu item dari setiap set instance yang sama.
Seseorang dapat menambahkan item, menghapus item dan memeriksa apakah set berisi item. Tetapi mengapa tidak mungkin untuk mendapatkan item tertentu dari 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
Satu-satunya cara untuk mengambil item saya adalah dengan mengulang seluruh koleksi dan memeriksa semua item untuk kesetaraan. Namun, ini membutuhkan O(n)
waktu, bukan O(1)
!
Saya belum menemukan bahasa yang mendukung dapatkan dari set sejauh ini. Semua bahasa "umum" yang saya tahu (Java, C #, Python, Scala, Haskell ...) tampaknya dirancang dengan cara yang sama: Anda dapat menambahkan item, tetapi Anda tidak dapat mengambilnya. Adakah alasan bagus mengapa semua bahasa ini tidak mendukung sesuatu yang mudah dan jelas bermanfaat? Mereka tidak mungkin salah, kan? Apakah ada bahasa yang mendukungnya? Mungkin mengambil kembali item tertentu dari set adalah salah, tetapi mengapa?
Ada beberapa pertanyaan terkait SO:
/programming/7283338/getting-an-element-from-a-set
/programming/7760364/how-to-retrieve-actual-item-from-hashsett
Set<E>
implementasi hanya Map<E,Boolean>
di dalam.
a == b
selalu benar) dalam kasus this.A == null
. The if (item == null || this.A == null || item.A == null)
uji "berlebihan" dan cek banyak, mungkin dalam rangka menciptakan artifisial "berkualitas tinggi" kode. Saya melihat semacam ini "pemeriksaan berlebihan" dan menjadi terlalu benar sepanjang waktu pada Tinjauan Kode.
std::set
mendukung pengambilan objek, jadi tidak semua bahasa "umum" seperti yang Anda gambarkan.