1

私は Scala を初めて使用し、私たちのプロジェクトでは Java と Scala のコードを (Play Framework を使用して) 組み合わせています。次のようなネストされた Java Map を取ることができる Scala メソッドを作成しようとしています。

LinkedHashMap<String, LinkedHashMap<String, String>> groupingA = new LinkedHashMap<String, LinkedHashMap<String,String>>();

そして、その Java オブジェクトをループ可能な Scala 関数に渡します。上記のJavaのネストされたマップを試してサポートするために、次のscalaオブジェクト定義があります。

Seq[(String, Seq[(String,String)])]

Java ファイルと Scala ファイルはどちらも個別に正常にコンパイルされますが、Java オブジェクトが scala クラスの新しいインスタンスを作成し、ネストされたマップを渡そうとすると、次の詳細でコンパイラ エラーが発生します。

[error]  ..... overloaded method value apply with alternatives:
[error]   (options: java.util.List[String])scala.collection.mutable.Buffer[(String, String)] <and>
[error]   (options: scala.collection.immutable.List[String])List[(String, String)] <and>
[error]   (options: java.util.Map[String,String])Seq[(String, String)] <and>
[error]   (options: scala.collection.immutable.Map[String,String])Seq[(String, String)] <and>
[error]   (options: (String, String)*)Seq[(String, String)]
[error]  cannot be applied to (java.util.LinkedHashMap[java.lang.String,java.util.LinkedHashMap[java.lang.String,java.lang.String]])

上記のようなネストされた Java LinkedHashMap を、ネストされたコレクションを一般的に反復できる Scala ファイルに渡す方法についてのアイデアはありますか? Java ではなく Scala で play フレームワーク コントローラーを記述することに切り替えた場合に備えて、ネストされた Scala コレクションでも機能するように、このジェネリックを十分に記述しようとしています。

4

2 に答える 2

1

これを試して:

import scala.collections.JavaConversions.mapAsScalaMap

val lhm: LinkedHashMap[String, LinkedHashMap[String, String]] = getLHM()
val scalaMap = mapAsScalaMap(lhm).mapValues(mapAsScalaMap(_).toSeq).toSeq

私はこれをテストし、タイプの結果を得ましたSeq[String, Seq[(String, String)]]

(変換は、実際に値のコピーを使用して Scala オブジェクトを作成するのではなく、元の Java オブジェクトをラップします。したがって、Seq への変換は必要ありません。Map のままにしておくことができます。反復順序は同じになります) .

推測させてください、クエリパラメーターを処理していますか?

于 2012-10-03T19:19:22.080 に答える
1

SeqScala Collections 階層で定義された基本的な特性です。java と scala はバイト コードの互換性を提供しますが、scala は独自のコレクション ライブラリを含む独自の型を多数定義します。ここで厄介なのは、慣用的な scala を書きたい場合は、Java データを scala データに変換する必要があることです。私の見方では、いくつかのオプションがあります。

  • Richard のソリューションを使用して、scala コードで Java 型を scala 型に変換できます。入力が常にJavaランドから来ると想定しているため、これは醜いと思います。

  • 美しく完璧な scala ハンドラーを作成し、醜い Java 変換動作を提供するコンパニオン オブジェクトを提供できます。これにより、scala 実装が Java の詳細から切り離されます。

  • または、以下のような暗黙的な定義を作成して、思いのままに一般化することもできます。

.

import java.util.LinkedHashMap
import scala.collection.JavaConversions.mapAsScalaMap

object App{
  implicit def wrapLhm[K,V,G](i:LinkedHashMap[K,LinkedHashMap[G,V]]):LHMWrapper[K,V,G] = new LHMWrapper[K,V,G](i)

  def main(args: Array[String]){
    println("Hello World!")
    val lhm = new LinkedHashMap[String, LinkedHashMap[String,String]]()
    val inner = new LinkedHashMap[String,String]()
    inner.put("one", "one")
    lhm.put("outer",inner);
    val s = lhm.getSeq()
    println(s.toString())
  }
  class LHMWrapper[K,V,G](value: LinkedHashMap[K,LinkedHashMap[G,V]]){
    def getSeq():Seq[ (K, Seq[(G,V)])] = mapAsScalaMap(value).mapValues(mapAsScalaMap(_).toSeq).toSeq
  }
}
于 2012-10-03T19:42:39.937 に答える