如何“更新”Scala中不可变集合中的不可变元素?

时间:2013-02-05 20:49:59

标签: scala set immutability

我有一个Set个元素,它们在一个键周围定义了相等,但其他字段可能不同......所以当我需要'更新'时,这就是我尝试过的:

object sandbox {

  case class K(val id: Int, val message: String) {
    override def equals(that: Any) = that match {
      case K(this.id, _) => true
      case _ => false
    }
    override def hashCode = this.id
    override def toString = "(" + id + "," + message + ")"
  }

  val s = Set(K(1, "a"), K(2, "b"))               //> s  : scala.collection.immutable.Set[test.sandbox.K] = Set((1,a), (2,b))
  val updatedElem = K(1, "c")                     //> updatedElem  : test.sandbox.K = (1,c)

  s + updatedElem                                 //> res0: scala.collection.immutable.Set[test.sandbox.K] = Set((1,a), (2,b))

  Set(updatedElem) | s                            //> res1: scala.collection.immutable.Set[test.sandbox.K] = Set((1,c), (2,b))
  }

添加已经存在的元素将不会更改该集合,并且首先将其删除并再次添加更新似乎是次优的。

union方法保留左侧集合的元素,但不记录该行为;所以我不应该依赖它。

所以,现在,有什么比我更缺失的事情了吗?我应该依赖于实际行为(并且只是在它发生变化的情况下编写测试)吗?或者我应该分两步进行更新?

1 个答案:

答案 0 :(得分:5)

从我的观点来看,它实际上是建模中的概念问题。关键是等于对象应该是等价的......否则你可能想要考虑其他一些结构。例如,为什么不尝试将Map映射到id(或messageid)的K(id,message)?在概念中看起来更清晰,然后您可以使用.updated(1,"c")来更新它。