SequenceとList(Array)

TL;DR

Sequence1つの値に対する操作が全て行われた後、必要なら次のが処理される。
Listすべての値に対して1つの操作が行われた後、必要なら次の操作が行われる

Kotlinでのデータの集合

Kotlinにはデータの集合を操作するためのクラスとして、List, Array, Sequenceがあります。
ListやArrayは他の多くに言語にもあるため想像がつくかと思います。では、Sequenceとは何なのでしょうか?
Sequenceを理解するためにList, Arrayとの違いをみていきましょう。

List vs Array

ListArrayはそれぞれの要素に対して操作を行うという観点ではほとんど同じと言えます。大きな違いとしてはArrayJavaの配列型と同等の扱いになります。Javaとの互換性を保つためにArrayがあると推測できます。

以降の文ではArrayは無視してSequenceListについて書いていきます。

Sequence vs List

実際の処理を見ると違いがわかりやすいので、
(1, 2, 3, 4)の値を持ったSequenceとListに対して以下の処理を行う場合の動作をみていきます

  1. それぞれの要素を二乗する : map{v -> v * v}
  2. それぞれの要素に1を足す : map{v -> v + 1}
  3. 値が5の要素を除く : filter{v != 5}
  4. 残った要素から最初に2つを取り出す: take(2)
  5. 1〜4の結果を出力: foreach{ v -> println(v)}

処理過程

操作の過程を以下の表に示します。

f:id:scache:20180419000703p:plain:w300f:id:scache:20180419000707p:plain:w300

Sequenceの4の列がすべて空白になっています(書き忘れじゃないですよ)。
今回の場合、Sequenceでは値4に対してまったく操作が行われません。ここがListとの大きな違いとなります。

Sequenceでは遅延評価が行われ、値1に対する操作(map -> map -> filter -> take)がすべて終わった後に値2,3の操作が行われます。
13のtake(2)が終わった段階でtake(2)の結果が決定するため値4の処理は行われません。

一方、Listの場合は値14に対してmap(v*v)の操作を行った結果のListを作成します。作成されたListに対してさらにmap(v+1)の操作, さらにfilter(), take()と続きます。

f:id:scache:20180419000652p:plain:w300f:id:scache:20180419000656p:plain:w300

まとめ

Sequence1つの値に対する操作が全て行われた後、必要なら次のが処理される。
Listすべての値に対して1つの操作が行われた後、必要なら次の操作が行われる

※ Sequenceは実際に値が必要になるまで処理が行われない(遅延される)などの違いもあります。

参考

kotlin.sequences - Kotlin Programming Language