SCALAで、異なるEquals/Hashcode/Compartedementの実装を使用するコレクションを作成できますか?
-
27-09-2019 - |
質問
アイデンティティセットを作成する簡単な方法を探しています。グラフを横断しながら特定のオブジェクトを「見た」かどうかを追跡できるようになりたいだけです。
セットは "=="(ScalaのEqualsメソッド)を使用して要素を比較するため、通常のセットを使用できません。私が欲しいのは、「eq」を使用するセットです。
SCALAで、設定された要素に等しい呼び出しを呼び出すのではなく、平等をテストするためにいくつかのアプリケーションで指定された方法を使用するセットを作成する方法はありますか?私はオーバーライドすることができたが、それを見つけられなかったある種の「wrapequals」方法を探しました。
JavaのIdentityhashmapを使用できることは知っていますが、より汎用的なものを探しています。
私が持っていたもう1つのアイデアは、EQの観点から等しいものを実装する別のオブジェクトに各セット要素をラップすることでしたが、新しい等しい実装を取得するためだけに大量の新しいオブジェクトを生成することは無駄です。
ありがとう!
解決
これ 同様の質問です。その場合の受け入れられた答えは、 TreeSet
カスタムを提供します Comparator
.
他のヒント
ニーズに応じて、次のような含まれている要素でアイデンティティチェックを使用するボックスを作成できます。
class IdentBox[T <: AnyRef](val value: T) {
override def equals(other: Any): Boolean = other match {
case that: IdentBox[T] => that.value eq this.value
case _ => false
}
override def hashCode(): Int = value.hashCode
}
要素の代わりにそれらのボックスを直接含めるようにコレクションを作成します。
ボクシング /ボクシングのオーバーヘッドがありますが、ユースケースでは許容できる場合があります。
「見た」オブジェクトへの参照は必要ありませんが、「contains」のブール値だけを使用することをお勧めします。 mutable.Set[Int]
呼び出しによって取得された値でそれをロードします System.identityHashCode(obj)
.
Scala Custom Collectionには、このような簡単な調整が必要なほとんどの人を怖がらせるのに十分な概念的な表面積があります。