2

我将在 Scala 中创建 JDBC ResultSet 的包装器。
这个包装器旨在成为一个函数ResultSet => ParticularType
问题是我找不到制作 MultiMaps 的通用解决方案。

这是我获取集合的方式:

抽象类 CollectionCreator[C] 扩展 (ResultSet => C) {  
  def apply(rs: ResultSet): C = {  
    做 { append(rs) } while (rs.next)  
    返回集合()  
  }  
  def 附加(rs:结果集)  
  def returnCollection(): C
}

接下来是地图创建。它是集合创建的一种实现,由于映射非抽象性,它不是抽象的(在我的实现中它总是以 HashMap 为后端)。
在我看来,它应该是这样的:

类 MapCreator[K,IV](keyCreator: ResultSet => K, valueCreator: ResultSet => IV)
  扩展 CollectionCreator[Map[K, Place for V]] {

  类型 V = IV
  val middleMap = new HashMap[K, V]

  覆盖 def append(rs: ResultSet) {
    appendToMap(keyCreator(rs), valueCreator(rs))
  }

  def appendToMap(键:K,值:IV){
    中间映射(键)= 值
  }

  覆盖 def returnCollection(): Map[K,V] = intermediateMap.toMap
}

如果可行,我会这样编写 ListMultiMap 创建:

类 ListMultiMapCreator[K,IV](keyCreator: ResultSet => K, valueCreator: ResultSet => IV)
  扩展 MapCreator[K, 放置 V](keyCreator, valueCreator) {

  覆盖类型 V = List[IV]

  覆盖def appendToMap(键:K,值:IV){
    中间映射(键)=中间映射.get(键)匹配{
      case Some(values) => values.::(value)
      案例无 => 列表(值)
    }
  }
}

问题是我不能使用VatPlace for V因为它当时没有声明。
我觉得抽象类型是很好的解决方案,但不知道如何正确对待它们。

这样的集合创建的正确方法是什么?

我也不确定是否可以覆盖已经在类层次结构中定义的抽象类型。

4

1 回答 1

2

在你的定义中,MapCreator确实是约束IVV是同一类型。根据合同,V返回的 inMap[K,V]必须与返回的类型相同valueCreator。例如,如果我打电话给:

MapCreator((rs:ResultSet) => rs.getString("KEY"),
    (rs:ResultSet) => rs.getString("VALUE"))(resultSet)

我希望得到一个Map[String,String]. 如果扩展 ,则无法更改该关系MapCreator。如果你想要一个Map[String,List[String]],你需要提供一个valueCreator类型(ResultSet) => List[String]

考虑到这一点,您可以像这样更改定义和实现:

class MapCreator[K,IV](keyCreator: ResultSet => K, 
    valueCreator: ResultSet => IV) extends CollectionCreator[Map[K, IV]] { 
  val intermediateMap = new HashMap[K, IV]
  def append(rs: ResultSet) { appendToMap(keyCreator(rs), valueCreator(rs)) }
  def appendToMap(key: K, value: IV) { intermediateMap(key) = value }
  def returnCollection(): Map[K, IV] = intermediateMap.toMap
}

class ListMultiMapCreator[K,IV](keyCreator: ResultSet => K, 
    elemCreator: ResultSet => IV) extends 
  MapCreator[K, List[IV]](keyCreator, 
      (rs:ResultSet) => List(elemCreator(rs))) {
  override def appendToMap(key: K, value: List[IV]) {
    intermediateMap(key) = intermediateMap.get(key) match {
      case Some(values) => values.:::(value)
      case None         => value
    }
  }
}

我觉得因为CollectionCreator使用了类型参数,所以使用抽象类型会很麻烦。总的来说,似乎有很多样板。我会利用更多的 scala 库:

def mapCreate[K, IV](rs: ResultSet, 
    keyCreator: ResultSet => K, 
    valueCreator: ResultSet => IV) = {
  Iterator.continually(rs).takeWhile(_.next).map{rs => 
    keyCreator(rs) -> valueCreator(rs)}.toMap
}

def listMultiMapCreate[K, IV](rs: ResultSet, 
    keyCreator: ResultSet => K, 
    valueCreator: ResultSet => IV) = {
  Iterator.continually(rs).takeWhile(_.next).map{rs => 
    keyCreator(rs) -> valueCreator(rs)}.toList.groupBy(_._1)
}

do { append(rs) } while (rs.next)如果结果集为空怎么办?

于 2011-04-08T12:11:53.113 回答