Hãy có lớp C # này (nó sẽ gần giống với 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;
}
}
Như bạn có thể thấy, sự bình đẳng của hai trường hợp chỉ MyClass
phụ thuộc vào A
. Vì vậy, có thể có hai trường hợp bằng nhau, nhưng giữ một phần thông tin khác nhau trong B
tài sản của họ .
Trong một thư viện bộ sưu tập tiêu chuẩn gồm nhiều ngôn ngữ (bao gồm cả C # và Java, tất nhiên) có một Set
( HashSet
trong C #), một bộ sưu tập, có thể chứa tối đa một mục từ mỗi bộ phiên bản bằng nhau.
Người ta có thể thêm các mục, loại bỏ các mục và kiểm tra xem bộ có chứa một mục không. Nhưng tại sao không thể có được một mặt hàng cụ thể từ bộ này?
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
Cách duy nhất để lấy lại mục của tôi là lặp lại toàn bộ bộ sưu tập và kiểm tra tất cả các mục để tìm sự bình đẳng. Tuy nhiên, điều này cần có O(n)
thời gian thay vì O(1)
!
Tôi chưa tìm thấy bất kỳ ngôn ngữ nào hỗ trợ có được từ một bộ cho đến nay. Tất cả các ngôn ngữ "phổ biến" mà tôi biết (Java, C #, Python, Scala, Haskell ...) dường như được thiết kế theo cùng một cách: bạn có thể thêm các mục, nhưng bạn không thể truy xuất chúng. Có bất kỳ lý do chính đáng tại sao tất cả các ngôn ngữ này không hỗ trợ một cái gì đó dễ dàng và rõ ràng hữu ích? Họ không thể sai được, phải không? Có ngôn ngữ nào hỗ trợ nó không? Có thể lấy lại một mục cụ thể từ một bộ là sai, nhưng tại sao?
Có một vài câu hỏi SO liên quan:
/programming/7283338/getting-an-element-from-a-set
/programming/7760364/how-to-retrieve-actual-item-from-hashsett
Set<E>
triển khai chỉ Map<E,Boolean>
ở bên trong.
a == b
luôn luôn đúng) trong trường hợp this.A == null
. Các if (item == null || this.A == null || item.A == null)
thử nghiệm là "quá trớn" và kiểm tra nhiều, có thể để tạo ra nhân tạo "chất lượng cao" mã. Tôi thấy loại "kiểm tra quá mức" này và luôn luôn chính xác trong Đánh giá mã.
std::set
hỗ trợ truy xuất đối tượng, vì vậy không phải tất cả các ngôn ngữ "thông thường" đều giống như bạn mô tả.