web-dev-qa-db-ja.com

Java.lang.Iteratorから不変のリストを作成します

一致する要素を抽出するために、ライブラリ( JXPath )を使用してBeanのグラフをクエリしています。ただし、JXPathは一致する要素のグループをJava.lang.Iteratorのインスタンスとして返すため、不変のscalaリストに変換したいと思います。反復するよりも簡単な方法はありますか。イテレータを超えて、各反復ステップで新しい不変リストを作成しますか?

22
Romain Rouvoy

Listの必要性を再考することをお勧めしますが、Javaから来ると非常に馴染みがあり、Listは不変のSeqのデフォルトの実装ですが、多くの場合、最良の選択ではありません。コレクションの。

リストが最適な操作は、イテレータを介してすでに利用可能な操作です(基本的に、連続するヘッド要素と先頭要素を取得します)。イテレータが必要なものをまだ提供していない場合は、リストが最良の選択ではないことをほぼ保証できます。ベクトルの方が適切です。


JavaとScalaコレクションの間で変換するための推奨される手法(Scala 2.8 .1)経由 scala.collection.JavaConverters 。これにより、JavaConversionsよりも詳細に制御でき、暗黙的な競合の可能性を回避できます。

この方法では、直接暗黙の変換は行われません。代わりに、asScalaメソッドとasJavaメソッドをコレクションに追加して、変換を明示的に実行できるようにします。

Javaイテレータをa Scalaイテレータに変換するには:

javaIterator.asScala

JavaイテレータをScalaリストに変換するには(scalaイテレータを介して):

javaIterator.asScala.toList

toSeqの代わりにtoListを変換することを検討することもできます。イテレータの場合、これはStreamを返します。これにより、よりリッチなSeqインターフェイス内でイテレータの遅延動作を保持できます。

EDIT:toVectorメソッドはありませんが、(Danielが指摘したように)toIndexedSeqメソッドがあります。 VectorをデフォルトのIndexedSeqサブクラスとして(ListがデフォルトのSeqであるのと同じように)。

javaIterator.asScala.toIndexedSeq
34
Kevin Wright

EDIT:おそらく Kevin Wrightの答え を見る必要があります。これはScala 2.8.1、暗黙の魔法が少ない。


_scala.collection.JavaConversions_ から暗黙的な変換をインポートしてから、新しいScalaコレクションをシームレスに作成できます(例:次のように))。

_import collection.JavaConversions._
println(List() ++ javaIterator)
_

あなたのJavaイテレータは_JavaConversions.asScalaIterator_によってScalaイテレータに変換されます。AScalaタイプの要素を持つイテレータAは_TraversableOnce[A]_を実装します。これは、コレクションを_++_と連結するために必要な引数タイプです。

別のコレクションタイプが必要な場合は、List()を必要なものに変更するだけです(例:IndexedSeq()またはcollection.mutable.Seq()など)。