Collection 个案例 class 个实例保留了单个字段的唯一性

Collection of case class instances preserving uniqueness of a single field

假设您有一个案例 class SearchQualifier,其中包含两个字段 leftright。它可以添加到某些 SearchQuery class 的实例中以限定搜索(例如 SearchQualifier("date", "January 1, 2000"))。

case class SearchQualifier(left: String, right: String)

现在,假设您有 collection 个 SearchQualifiers。如果您向 collection 添加一个新的限定符,并且 left 与另一个相同,则您的意图是覆盖先前的值。例如:

qualifiers = qualifiers + Qualifier("date", "January 1, 2000")
...
qualifiers = qualifiers + Qualifier("date", "December 31, 1999") // override

是否有一种干净的方法来保持基于 left 的限定符的唯一性?

我目前的方法是使用 Map[String, Qualifier],其中映射键是 left,但感觉像是 hack:

map = map + (qual.left -> qual)

理想情况下,我更喜欢类似 Set 的行为。但是,我认为覆盖 equals 以仅检查 left 是不正确的,因为 SearchQualifier("date", "January 1, 2000")SearchQualifier("date", "December 31, 1999") 而不是 平等的。

Map 似乎是适合您的完美数据结构,根本不是 hack。将 Map 视为基本上是 Set 是完全合理的,其中每个元素都与一个值相关联。事实上,Map 有一个方法 .keySet,其中的键是 return 给你作为 Set,它支持这个论点。正如您所指出的,覆盖 .equals 只是为了在 Set 中获得该行为确实令人困惑。

我认为最简单的解决方案是使用 TreeSet

  val searchQualifierOrderingByLeft = new Ordering[SearchQualifier] {
    override def compare(x: SearchQualifier, y: SearchQualifier): Int = 
      if (x.left == y.left) 0 else 1
  }

  val ts = TreeSet[SearchQualifier](SearchQualifier("l1", "r1"),
                                    SearchQualifier("l1", "r2"),
                                    SearchQualifier("l2", "r1"))(searchQualifierOrderingByLeft)

      println(ts) // TreeSet(SearchQualifier(l1,r2), SearchQualifier(l2,r1))