在'hashCode()'

时间:2017-05-21 05:43:47

标签: scala override hashcode

它发生在id。 (非值字段在'hashCode()'中访问)

我该如何解决?

这是我的代码:

import java.util.Date

case class Category() {
    var id: Integer = _
    var parentId: Integer = _
    var name: String = _
    var status: Boolean = _
    var sortOrder: Integer = _
    var createTime: Date = _
    var updateTime: Date = _

    def this(id: Integer, parentId: Integer, name: String, status: Boolean, sortOrder: Integer, createTime: Date, updateTime: Date) {
        this()
        this.id = id
        this.parentId = parentId
        this.name = name
        this.status = status
        this.sortOrder = sortOrder
        this.createTime = createTime
        this.updateTime = updateTime
    }

    override def hashCode(): Int = {
        if (id != null) id.hashCode() else 0
    }
}

如果我将var id更改为val id,则可以。但是我需要setter,我不能把它设置为val。

2 个答案:

答案 0 :(得分:1)

hashCode中的非值字段表示您正在中继可变字段以生成类哈希码,这可能很危险,具体取决于您使用该类的方式。例如,假设您有HashMap[Category, String],您在哈希映射中放置一个条目,并且它们会改变id字段,现在hashmap不再能够通过它的哈希码找到类实例。

您正在对案例类进行处理,因为它是一个常规的,可变的Java类。 Case类提供了以语法方便的方式封装 immutable 数据的机制(在这里你也可以免费获得一些好东西,比如hashCodeequals等)。你可以做的是让你的case类通过它的主要构造函数接受参数:

case class Category(id: Int,
                    parentId: Int,
                    name: String,
                    status: Boolean,
                    sortOrder: Int,
                    createTime: Date,
                    updateTime: Date) {
  override def hashCode(): Int = id.hashCode()
}

如果您要更新Category,可以使用案例类中定义的实用程序copy方法:

val cat = Category(id = 1,
                   parentId = 1,
                   name = "Hello",
                   status = true,
                   sortOrder = 1,
                   createTime = new Date(123132123L),
                   updateTime = new Date(52234234L))

val newCat: Category = cat.copy(id = 2)

另一种接近此方式(我更喜欢TBH)的方法是将所有字段设为Option[T],默认值设置为None

case class Category(id: Option[Int] = None,
                    parentId: Option[Int] = None,
                    name: Option[String] = None,
                    status: Option[Boolean] = None,
                    sortOrder: Option[Int] = None,
                    createTime: Option[Date] = None,
                    updateTime: Option[Date] = None) {
  override def hashCode(): Int = id.map(_.hashCode()).getOrElse(0)
}

然后,一旦您可以使用数据填充类,就更新它们:

val cat = Category()
val newCat = cat.copy(id = Some(1))

答案 1 :(得分:0)

在我尝试多次之后,我认为这应该是一个不错的选择。 有任何想法吗?

override def hashCode(): Int = {
    if (getId != null) getId.hashCode() else 0
}