2016-08-25 7 views
3
私は、一般的なスカラ座 SeqへのJava Listから変換するときに、私は実際にこのコードで何が起こっているかのより良い理解を得たい

スカラ:配列を返す関数から変更可能なバッファを返す

import scala.collection.JavaConverters._ 

def foo(javaList: java.util.List[String]): Seq[String] = { 
    val scalaMutableBuffer: mutable.Buffer[String] = javaList.asScala 
    scalaMutableBuffer 
} 

... 

val bar = foo(someJavaList) 

barSeq[String]と入力されていますが、Seq操作のパフォーマンスに影響を及ぼす可能性のある可変バッファを使用していることを正しく理解していますか? Seqは単にSeq特性の制約を使ってバッファを参照しているのですか、それとも実際に起こっている実際の変換ですか?値がbarの場合、変更可能または不変であると考えるのが最善でしょうか?

この質問は、どのようにオープンエンドであったのですか、私は何が起こっているのか良いアイデアがあるとは思わないし、それを変更したいと思います。たとえば、fooに戻る前にscalaMutableBuffertoListに変換することが望ましい場合はありますか?

ありがとうございます!

答えて

4

バーは、配列[文字列]として入力されている間、それはあなたが正しい 基本となるレベル

に変更可能なバッファを使用しています、barの実行時の値はとしてmutable.ArrayBuffer[String](ありますBufferは特性そのものです)、Seq[+A]は特性ですので、発信者はの "sequency"部分を見るだけですが、いつでもbuffer.asInstanceOf[mutable.ArrayBuffer[String]]経由でバッファにキャストしてから実際の "internals"バッファの潜在的に1はSeq[A]を公開すると、あなたは、基になるコレクションが付着することを「契約」をさらすいる

配列操作のパフォーマンスに影響を与える

。実行時には、常に具体的な実装になります。つまり、私たちはapply経由Seqを作成するとき:

scala> Seq(1,2,3) 
res0: Seq[Int] = List(1, 2, 3) 

具体的な実装は、実際にList[Int]です。

値バーには可変値が含まれていると思いますか? 不変ですか?

基本的な実装は変更可能ですが、不変の契約によって公開されます。これは、Seq特性の抽象化を介してバッファ上で操作しているときに、呼び出し側として利用可能な変更可能な操作がないことを意味します。私たちは例えば

、:

scala> val bufferAsSeq: Seq[Int] = scala.collection.mutable.Buffer(1,2,3) 
bufferAsSeq: Seq[Int] = ArrayBuffer(1, 2, 3) 

scala> bufferAsSeq += 4 
<console>:12: error: value += is not a member of Seq[Int] 
     bufferAsSeq += 4 

抽象化は、ユーザーをさせるから私たちを守るには、我々は、実行時の型で行うためにそれらを望まない操作を呼び出します。例えば

、私はこれは主にベースの意見だと思う私がfoo

から復帰する前にscalaMutableBuffer ToListメソッドを変換することが 望ましいだろうするあらゆるケースが存在することになります。 Seqの特性を感じていない場合、具体的な型は常に不変であることができます。しかし、誰かがSeqのコピーを変更するためには、ランタイムタイプを確認してを明示的にキャストしてとし、すべてのベットをオフにしてキャストしてください。

+0

答えに感謝します。私はScalaの可変性に対して腸管反応を起こしますが、現実的に不変性は、JVMの多くの変更可能性の上にある抽象であり、この場合でもSeqは不変性の抽象化を提供しているようです。 – Nathan

+0

@ネイサン私はあなたの腸の感覚を理解しています。 Scalaを使って作業するときは、永遠に不変性のために努力したいと思っています。しかし、再び、あなたのケースでは 'Seq'抽象化を回避し、実際には変更可能なコレクションの変更可能性を使用するために、一生懸命働かなければならないでしょう。 –

+0

私が 'bar.asInstanceOf [scala.collection.mutable.Buffer [String]]'と呼んだ場合、Seqインターフェースを使ってSeqから可変バッファに一般的な変換を行っていますか?基礎となるバイナリ表現を使った生のキャスト? – Nathan

関連する問題