Map of with object references as keys?

前端 未结 3 1758
[愿得一人]
[愿得一人] 2021-01-14 17:37

I have an object with stores information about specific instances. For that, i would like to use a Map, but as the keys are not by-reference (they aren\'t, rig

3条回答
  •  南方客
    南方客 (楼主)
    2021-01-14 18:16

    EDIT: Based on clarifications to the question, you can create your own Map implementation, and override elemEquals().

    The original implementation (in HashMap)

    protected def elemEquals(key1: A, key2: A): Boolean = (key1 == key2)
    

    Change this to:

    protected def elemEquals(key1: A, key2: A): Boolean = (key1 eq key2)
    
    class MyHashMap[A <: AnyRef, B] extends scala.collection.mutable.HashMap[A, B] {
      protected override def elemEquals(key1: A, key2: A): Boolean = (key1 eq key2)
    }
    

    Note that to use eq, you need to restrict the key to be an AnyRef, or do a match in the elemEquals() method.

    case class Foo(i: Int)
    val f1 = new Foo(1)
    val f2 = new Foo(1)
    val map = new MyHashMap[Foo, String]()
    map += (f1 -> "f1")
    map += (f2 -> "f2")
    map.get(f1) // Some(f1)
    map.get(f2) // Some(f2)
    

    -- Original answer

    Map works with hashCode() and equals(). Have you implemented equals() correctly in your obejcts? Note that in Scala, == gets translated to a call to equals(). To get the same behaviour of == in Java, use the Scala operator eq

    case class Foo(i: Int)
    val f1 = new Foo(1)
    val f2 = new Foo(1)
    f1 == f2 // true
    f1.equals(f2) // true
    f1 eq f2 // false
    
    val map = new MyHashMap (f1 -> "f1", f2 -> "f2")
    map.get(f1) // Some("f2")
    map.get(f2) // Some("f2")
    

    Here, the case class implements equals() to be object equivalence, in this case:

    f1.i == f1.i
    

    You need to override equals() in your objects to include object equality, i.e something like:

    override def equals(o: Any) = { o.asInstanceOf[AnyRef] eq this }
    

    This should still work with the same hashCode().

提交回复
热议问题