Looking for kotlin Answers? Try Ask4KnowledgeBase
Looking for kotlin Keywords? Try Ask4Keywords

KotlinJava 8ストリームに相当するもの


前書き

Kotlinは、関数型操作を適用するためのコレクションおよびiterableに関する多くの拡張メソッドを提供しています。専用のSequence型では、このような操作のいくつかを怠け者にすることができます。

備考

怠惰について

チェーンを遅延処理したい場合は、チェーンの前にasSequence()を使用してSequence変換できます。関数の連鎖の終わりには、通常、 Sequenceも終了します。次に、 toList()toSet()toMap()または他の関数を使用して、最後にSequenceを実現することができます。

// switch to and from lazy
val someList = items.asSequence().filter { ... }.take(10).map { ... }.toList()

// switch to lazy, but sorted() brings us out again at the end
val someList = items.asSequence().filter { ... }.take(10).map { ... }.sorted()

なぜ型がないのですか?

Kotlinの例では型が指定されていないことに気づくでしょう。これは、Kotlinが完全な型推論を持ち、コンパイル時に完全な型の安全であるためです。 Javaにはヌル可能な型があり、恐ろしいNPEを防ぐのに役立つので、Javaほどです。それでKotlinでこれは:

val someList = people.filter { it.age <= 30 }.map { it.name }

次のものと同じです:

val someList: List<String> = people.filter { it.age <= 30 }.map { it.name }

Kotlinは何を知っているのでpeopleあり、そのpeople.ageあるIntしたがって、フィルタ式はのみとの比較ができInt 、そのpeople.nameあるStringため、 mapステップが生成するList<String> (読み取り専用ListString )。

今、 List<People>?ようにpeopleがおそらくnull場合はList<People>?次に:

val someList = people?.filter { it.age <= 30 }?.map { it.name }

List<String>?返しますList<String>?null値を扱うためにこのKotlinの慣用的な方法を参照してください。また、 Kotlinで nullableまたは空のリストを処理 する慣習的な方法も参照してください

ストリームの再利用

コトリンでは、それが1回以上消費されるかどうかは、収集のタイプに依存する。 Sequenceは毎回新しいイテレータを生成し、「1回のみ使用」をアサートしない限り、動作するたびに開始にリセットすることができます。したがって、Java 8ストリームでは次のように失敗しますが、Kotlinでは動作します。

// Java:
Stream<String> stream =
Stream.of("d2", "a2", "b1", "b3", "c").filter(s -> s.startsWith("b"));

stream.anyMatch(s -> true);    // ok
stream.noneMatch(s -> true);   // exception
// Kotlin:  
val stream = listOf("d2", "a2", "b1", "b3", "c").asSequence().filter { it.startsWith('b' ) }

stream.forEach(::println) // b1, b2

println("Any B ${stream.any { it.startsWith('b') }}") // Any B true
println("Any C ${stream.any { it.startsWith('c') }}") // Any C false

stream.forEach(::println) // b1, b2

そして、Javaでは同じ動作を得る:

// Java:
Supplier<Stream<String>> streamSupplier =
    () -> Stream.of("d2", "a2", "b1", "b3", "c")
          .filter(s -> s.startsWith("a"));

streamSupplier.get().anyMatch(s -> true);   // ok
streamSupplier.get().noneMatch(s -> true);  // ok

したがって、Kotlinでは、データのプロバイダがリセットして新しいイテレータを提供するかどうかを決定します。しかし、意図的にSequenceを1回の反復に制限したい場合は、次のようにSequence constrainOnce()関数を使用できます。

val stream = listOf("d2", "a2", "b1", "b3", "c").asSequence().filter { it.startsWith('b' ) }
        .constrainOnce()

stream.forEach(::println) // b1, b2
stream.forEach(::println) // Error:java.lang.IllegalStateException: This sequence can be consumed only once. 

参照:

Java 8ストリームに相当するもの 関連する例