Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java HashMap在对象发生变化时自动更新_Java_Scala_Hash_Hashmap - Fatal编程技术网

Java HashMap在对象发生变化时自动更新

Java HashMap在对象发生变化时自动更新,java,scala,hash,hashmap,Java,Scala,Hash,Hashmap,我有两个问题: 为什么HashMap使用密钥的内存地址作为标识符 用于地图输入,即bucket。据我所知,只要我 重写hashCode(),密钥的哈希代码将用作bucket 而不是我 为什么当密钥如中所述发生变化时,HashMap会得到更新 代码如下: 为什么HashMap使用键的内存地址作为映射项的标识符 没有。它使用密钥的哈希代码。(您认为它为什么使用内存地址?) 如果您想知道为什么键看起来像oo。Point2@20,这是因为您没有在类点中重写toString() 为什么当密钥发生变化时H

我有两个问题:

  • 为什么
    HashMap
    使用密钥的内存地址作为标识符 用于地图输入,即bucket。据我所知,只要我 重写
    hashCode()
    ,密钥的哈希代码将用作bucket 而不是我

  • 为什么当密钥如中所述发生变化时,
    HashMap
    会得到更新 代码如下:


  • 为什么HashMap使用键的内存地址作为映射项的标识符

    没有。它使用密钥的哈希代码。(您认为它为什么使用内存地址?)

    如果您想知道为什么键看起来像
    oo。Point2@20
    ,这是因为您没有在类
    点中重写
    toString()

    为什么当密钥发生变化时HashMap会得到更新

    因为
    HashMap
    不会复制用作键的对象;它只存储对键对象的引用。如果在将键放入
    HashMap
    后修改该键,则
    HashMap
    也会看到更改

    如果键对象的更改方式使其
    hashCode()
    方法返回不同的值(因为条目可能突然位于错误的存储桶中),则这将打乱您的
    HashMap

    不要修改在
    HashMap
    中用作键的对象,因为这会导致奇怪的问题(例如,对象可能会从映射中消失)。在
    HashMap
    中用作键的对象应该是不可变的

    为什么HashMap使用键的内存地址作为映射项的标识符

    没有。它使用密钥的哈希代码。(您认为它为什么使用内存地址?)

    如果您想知道为什么键看起来像
    oo。Point2@20
    ,这是因为您没有在类
    点中重写
    toString()

    为什么当密钥发生变化时HashMap会得到更新

    因为
    HashMap
    不会复制用作键的对象;它只存储对键对象的引用。如果在将键放入
    HashMap
    后修改该键,则
    HashMap
    也会看到更改

    如果键对象的更改方式使其
    hashCode()
    方法返回不同的值(因为条目可能突然位于错误的存储桶中),则这将打乱您的
    HashMap


    不要修改在
    HashMap
    中用作键的对象,因为这会导致奇怪的问题(例如,对象可能会从映射中消失)。在
    HashMap
    中用作键的对象应该是不可变的。

    不仅仅是HashMap。。这就是java的工作原理。。那也是出于某种原因。。如果你想让你的类不可变,那就让它不可变。它不仅仅是HashMap。。这就是java的工作原理。。那也是出于某种原因。。如果你想让你的类不可变,就让它不可变。实际上要求键不可变太严格了。要求密钥的标识不改变就足够了。不管怎么说,答案很好。如果钥匙的标识很重要的话,
    IdentityHashMap
    将是一个不错的选择。然后你可以自由地改变你的键。@Federicoperaltachaffner据我所知,参考值是一个对象的标识。将同一性视为参考值的同义词,那么这个名称就完全有意义了。@Durandal好的,我理解你的意思。我的意思是关于
    equals()
    合同的身份,即,如果您有一个
    个人
    对象,该对象具有
    社会安全号码
    姓名
    姓氏
    字段,那么关于
    equals()
    的身份将仅由
    社会安全号码
    字段定义,因为它在所有人中都是独一无二的。但实际上,这是平等而不是身份。我的错。@Luongbalin bucket更像是一个成对的链表:[(键1,值1),(键2,值2),…]而不是[(hashCode(键1,值1),(hashCode(键2,值2),…]),实际上要求键不可变太严格。要求密钥的标识不改变就足够了。不管怎么说,答案很好。如果钥匙的标识很重要的话,
    IdentityHashMap
    将是一个不错的选择。然后你可以自由地改变你的键。@Federicoperaltachaffner据我所知,参考值是一个对象的标识。将同一性视为参考值的同义词,那么这个名称就完全有意义了。@Durandal好的,我理解你的意思。我的意思是关于
    equals()
    合同的身份,即,如果您有一个
    个人
    对象,该对象具有
    社会安全号码
    姓名
    姓氏
    字段,那么关于
    equals()
    的身份将仅由
    社会安全号码
    字段定义,因为它在所有人中都是独一无二的。但实际上,这是平等而不是身份。我的错。@Luongbalin一个bucket更像是一个成对的链表:[(键1,值1),(键2,值2),…],而不是[(hashCode(键1,值1),(hashCode(键2,值2),…]
    object Equals {
      def main(args: Array[String]) {
        val pointX = new Point2(1, 1)
        val pointY = new Point2(2, 1)
        val pointZ = new Point2(4, 4)
        val map = HashMap(pointX -> "X", pointY -> "Y")
        println(s"Map before: $map")
        //Map before: Map(oo.Point2@20 -> X, oo.Point2@3f -> Y)
        pointX.move(3, 3)
        println(s"Map after: $map")
        //Map after: Map(oo.Point2@80 -> X, oo.Point2@3f -> Y)
        println(map(pointZ))
      }
    }
    class Point2(var x: Int, var y: Int) extends Equals {
      def move(mx: Int, my: Int): Unit = {
        x = x + mx
        y = y + my
      }
      override def hashCode(): Int = y + (31 * x)
      def canEqual(that: Any): Boolean = that match {
        case p: Point2 => true
        case _ => false
      }
      override def equals(that: Any): Boolean = {
        def strictEquals(other: Point2) =
        this.x == other.x && this.y == other.y
          that match {
            case a: AnyRef if this eq a => true
            case p: Point2 => (p canEqual this) && strictEquals(p)
            case _ => false
        }
      }
    }