2

ScalaでJDBCResultSetのラッパーを作成します。
このラッパーは関数として使用することを目的としていますResultSet => ParticularType
問題は、マルチマップを作成するための一般的な解決策が見つからないことです。

コレクションを取得する方法は次のとおりです。

抽象クラスCollectionCreator[C]extends(ResultSet => C){  
  def apply(rs:ResultSet):C = {  
    {append(rs)} while(rs.next)を実行します  
    returnCollection()  
  }  
  def append(rs:ResultSet)  
  def returnCollection():C
}

次はマップの作成です。これはコレクション作成の実装であり、マップが非抽象的であるため抽象的ではありません(私の実装では常にHashMapでバックエンドされています)。
私の意見では、次のようになります。

クラスMapCreator[K、IV](keyCreator:ResultSet => K、valueCreator:ResultSet => IV)
  CollectionCreator [Map [K、Place forV]]{を拡張します

  タイプV=IV
  val IntermediateMap = new HashMap [K、V]

  def append(rs:ResultSet){をオーバーライドします
    appendToMap(keyCreator(rs)、valueCreator(rs))
  }

  def appendToMap(key:K、value:IV){
    中間マップ(キー)=値
  }

  def returnCollection()をオーバーライドします:Map [K、V] = middleMap.toMap
}

それが機能する場合は、ListMultiMapの作成を次のように記述します。

クラスListMultiMapCreator[K、IV](keyCreator:ResultSet => K、valueCreator:ResultSet => IV)
  MapCreator [K、Place for V](keyCreator、valueCreator){を拡張します

  タイプVをオーバーライド=リスト[IV]

  def appendToMap(key:K、value:IV){をオーバーライドします
    中間マップ(キー)=中間マップ.get(キー)一致{
      case Some(values)=> values。::(value)
      ケースなし=>リスト(値)
    }
  }
}

問題は、その時点で宣言されていないため、でV使用できないことです。 抽象型は良い解決策だと思いますが、それらを正しく扱う方法がわかりません。Place for V

そのようなコレクションを作成する正しい方法は何ですか?

また、クラス階層の上位ですでに定義されている抽象型をオーバーライドできるかどうかもわかりません。

4

1 に答える 1

2

あなたの定義では、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)、結果セットが空の場合はどうなりますか?

于 2011-04-08T12:11:53.113 に答える