MultiMap的非法继承

时间:2018-12-03 15:20:56

标签: scala

我想创建一个MultiMap,该类具有一个键类和一个ListBuffer值。

我想添加多个将游戏对象扩展到地图中的对象。然后使用键检索一组对象。

GameObject

class GameObject {

}

工作人员

Staff extends GameObject {

}

客户

Customer extends GameObject {

}

示例

// Staff extends GameObject
val staffMembers = ListBuffer[Staff](/* Add Elements*/)

// Customer extends GameObject
val customers = ListBuffer[Customer](/* Add Elements*/)

val map = new mutable.HashMap[Class[_ <: GameObject], mutable.ListBuffer[GameObject]]() with mutable.MultiMap[Class[_ <: GameObject], GameObject]

staffMembers.foreach(staff=> map.addBinding(classOf[Staff], staff))
customers.foreach(customer=> map.addBinding(classOf[Customer], customer))

错误

Error:(34, 19) illegal inheritance;
<$anon: Class[_ <: com.casinogame.gameobject.GameObject] => 
scala.collection.mutable.ListBuffer[com.casinogame.gameobject.GameObject] with Class[_ <: com.casinogame.gameobject.GameObject] => 
scala.collection.mutable.Set[com.casinogame.gameobject.GameObject]> inherits different type instances of trait Map:
scala.collection.mutable.Map[Class[_ <: com.casinogame.gameobject.GameObject],scala.collection.mutable.Set[com.casinogame.gameobject.GameObject]] and scala.collection.mutable.Map[Class[_ <: com.casinogame.gameobject.GameObject],scala.collection.mutable.ListBuffer[com.casinogame.gameobject.GameObject]]
val map = new mutable.HashMap[Class[_ <: GameObject], mutable.ListBuffer[GameObject]]() with mutable.MultiMap[Class[_ <: GameObject], GameObject]

这样做的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

如果您更仔细地阅读文档,并用普通的可变ListBuffer替换嵌套的Set,那么编译就很好了:

import collection.mutable.ListBuffer
import collection.mutable.{Set, MultiMap, HashMap}

class GameObject {

}

class Staff extends GameObject {

}

class Customer extends GameObject {

}

// Staff extends GameObject
val staffMembers = ListBuffer[Staff](new Staff)

// Customer extends GameObject
val customers = ListBuffer[Customer](new Customer)

val map = 
  new HashMap[Class[_ <: GameObject], Set[GameObject]] 
  with MultiMap[Class[_ <: GameObject], GameObject]

staffMembers.foreach(staff=> map.addBinding(classOf[Staff], staff))
customers.foreach(customer=> map.addBinding(classOf[Customer], customer))

话虽如此,我认为以下代码片段更接近您的初衷:

val map2 = HashMap.empty[Class[_ <: GameObject], ListBuffer[GameObject]]

for (s <- staffMembers) {
  map2.getOrElseUpdate(classOf[Staff], ListBuffer.empty) += s
}
for (c <- customers) {
  map2.getOrElseUpdate(classOf[Customer], ListBuffer.empty) += c
}

如果将其包装在Builder中的Casino中,并且在构造Casino之后不要让可变状态在所有方向上逸出,甚至可以认为它是合理的惯用的。

答案 1 :(得分:0)

我不确定您为什么需要MultiMap,但这会创建一个简单的HashMap来将类映射到值:

val map = HashMap(List(
  classOf[Staff] -> staffMembers,
  classOf[Customer] -> customers
):_*)

如果在编译时固定了一组类,这还允许您使用不可变的Map