В вашем определении MapCreator
действительно ограничивает IV
и V
одним и тем же типом.По контракту V
, возвращаемое в Map[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)
, что если набор результатов будет пустым?