つかびーの技術日記

情報系修士卒のWeb系技術日記です。現在のフォーカス分野はアドテクです。

ScalaのListとJavaのListと配列(使い方や相互変換)

   

ScalaのListとJavaのListの使い方とかについてのメモです。

scala.List

scala.Listはイミュータブルです。Javaのようにaddしたりはできません。

addしたいのであれば以下のように再生成する必要があります。

:::はリストを連結して新しいリストを返却します。

scala.collection.mutable.ListBuffer

Javaユーザにとって上記のリストはなかなか辛い物があります。

ListBufferはパッケージ名から分かる通りミュータブルなので内部の構造を変えることができます。つまりJavaで言うArrayListと同じようなことができます。

+=で要素を追加しており、toListでリストに変換しています。

java.util.Listとjava.util.ArrayList

Scalaでは普通にJavaのライブラリなどが使えます。Java用のライブラリを利用する場合、そのライブラリがjava.util.Listを返却してくる場合があるかと思います。そういうケースも考慮してScalaでJavaのListも使えるようになっておいた方が良いと思います。

大体いつものJavaと同じ感じです。ArrayListはnewする必要があります。

また、JavaConversionsという暗黙の型変換を行ってくれるクラスをimportしてください。これが無いとfor式の部分で以下のようにコンパイルエラーが出てしまいます。

上記のfor式はあくまでScala用なのでJavaのListを受け付けてくれません。JavaConversionsをimportすると暗黙的にScalaのListに変換してくれるのでコンパイルが通る、という訳です。

java.util.Listからscala.Listへの変換

使用するライブラリなどによってscala.Listを受け付けているのか、java.util.Listを受け付けているのか変わってくると思います。上記2つは同じListとは言え、別の型ですので、ちゃんと意識しないとコンパイルエラーになります。

例えば先ほどの例とほぼ同じですが、以下はコンパイルエラーになります。

(Intellij上だとType mismatch, expected: List[Int], actual: List[Int]と出て一瞬「!?」となります。)

ではどうするのかというと以下のようにします。

JavaConverters._をimportすることでasScalaが使えるようになります。これで変換が可能です。asScalaではBuffer型になるため、ここではtoListしてscala.Listにしています。

scala.Listからjava.util.Listへの変換

これも同じです。JavaConverters様々ですね。

asJavaで変換できています。

scala.Listから配列への変換

まず以下のような配列を標準出力に吐き出すJavaコード(ライブラリ)があったとします。

scala.Listは型が違いのでそのままではprintArrayに与えてやることはできません。

これは簡単でtoArrayするだけです。

 java.util.Listから配列への変換

少しだけトリッキーですが、コード自体は全然大したこと無いです。

例によってJavaConvertersをimportした上でasScalaし、toArrayすればOKです。

javaList.toArrayのようにするとArray[AnyRef]が帰ってくるため、コンパイルが通りません。

javaList.toArray(new Array[Int](0))のようにするとコンパイルは通りますが、実行するとエラーになります。

詳しく調べてないので予想ですが、Javaで言うInteger(intのラッパークラス)の配列に変換されているからNGなのかな、と。

配列からscala.List, java.util.Listへの変換

普通にtoListとasJavaを使うだけですね。簡単!

やり方さえ分かってしまえばどうということは無いですが、若干面倒ですね。暗黙変換はまあ楽と言えば楽ですが。できれば使用するライブラリはscalaのもので揃えたいところですね。

以上、JavaおよびScalaのList, Arrayの使い方でした!

 - Scala ,