このC#クラスを作成しましょう(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;
}
}
ご覧のとおり、の2つのインスタンスが等しいMyClass
かどうかA
だけに依存しています。したがって、等しい2つのインスタンスが存在する可能性がありますが、それらのB
プロパティには異なる情報が保持されます。
多くの言語(もちろんC#とJavaを含む)の標準コレクションライブラリにはSet
(HashSet
C#で)があり、これは各インスタンスの等しいセットから最大1つの項目を保持できるコレクションです。
アイテムを追加、アイテムを削除し、セットにアイテムが含まれているかどうかを確認できます。しかし、セットから特定のアイテムを取得することが不可能なのはなぜですか?
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
アイテムを取得する唯一の方法は、コレクション全体を反復処理し、すべてのアイテムが等しいかどうかを確認することです。ただし、これにはO(n)
代わりに時間がかかりますO(1)
!
これまでのところ、セットからの取得をサポートする言語は見つかりませんでした。私が知っているすべての「共通」言語(Java、C#、Python、Scala、Haskell ...)は同じように設計されているようです。アイテムを追加することはできますが、取得することはできません。これらすべての言語がそれほど簡単で明らかに役立つものをサポートしない理由はありますか?それらはすべて間違っているとは限りませんよね?それをサポートする言語はありますか?セットから特定のアイテムを取得するのは間違っているかもしれませんが、なぜですか?
関連するSOの質問がいくつかあります。
/programming/7283338/getting-an-element-from-a-set
/programming/7760364/how-to-retrieve-actual-item-from-hashsett
Set<E>
実装がMap<E,Boolean>
内部にあります。
a == b
、caseの反射性を破壊します(常にtrue)this.A == null
。if (item == null || this.A == null || item.A == null)
試験は、おそらく人工的に「高品質」コードを作成するために、はるかに「行き過ぎ」をチェックします。この種の「オーバーチェック」が見られ、Code Reviewでは常に過度に正確になっています。
std::set
はオブジェクトの取得をサポートしているため、すべての「共通」言語があなたの説明通りであるとは限りません。