Javaでは Stream API を利用することで、配列やコレクションなどの集合体から、特定の条件でデータを抽出したり、中身を別の型のコレクションに移し替えたり、合計値を求める時など、コレクションに対する操作を for 構文などの繰り返しを使わない形で値の集合を操作する事が出来ますが、Kotlinではこれらのコレクション操作がネイティブに利用することが出来ます。
今回はその中でもよく利用する機能をJava のStream API と比較しながら一覧に纏めました。Kotlinは、Java に比べると少ないコード量で完結にコードが記述することが出来ます。
よく使う コレクション操作 の一覧
使用するサンプルデータ
val userList = mutableListOf(
User(1, "teamA", 30),
User(2, "teamB", 50),
User(3, "teamA", 10),
User(4, "teamB", 40)
)
forEach
forEach は、要素を1つずつ取り出し何らかの処理をするメソッドです。
// Java
userList.stream()
.forEach(System.out::print);
// Kotlin
userList
.forEach { obj: User -> print(obj) }
// user1 user2 user3 user4
filter
filter は、引数で指定した条件に一致する要素を抽出するメソッドです。
// Java
userList.stream()
// teamBのみに抽出
.filter(e -> "teamB".equals(e.team))
.forEach(System.out::print);
// Kotlin
userList
// teamBのみに抽出
.filter { e: User -> "teamB" == e.team }
.forEach { obj: User -> print(obj) }
// user2 user4
map
map は、リストの要素を別の型に変換するメソッドです。
// Java
userList.stream()
// IDだけのリストに加工
.map(e -> e.id)
.forEach(System.out::print);
// Kotlin
userList
// IDだけのリストに加工
.map { e: User -> e.id }
.forEach { obj: Int -> print(obj) }
// 1 2 3 4
flatMap
flatMapは、mapと同じく リスト の要素を別の型に変換するメソッドです。map が1対1で要素の型を変換するのに対し、flatMap は1対多で変換をします。
つまり、入力した要素を複数の値に増殖するときなどに flatMap を使用します。
// Java
userList.stream()
// IDとチームのリストに加工
.flatMap(e -> Stream.of(e.id, e.team))
.forEach(System.out::print);
// Kotlin
userList
// IDとチームのリストに加工
.flatMap { e: User -> listOf(e.id, e.team) }
.forEach { obj: Serializable -> print(obj) }
// 1 teamA 2 teamB 3 teamA 4 teamB
distinct
distinctは、リスト の要素の中で、値もしくわ指定したキーが重複している要素を取り除くメソッドです。
// Java
userList.stream()
.map(e -> e.team)
// チームの重複を取り除く
.distinct()
.forEach(System.out::print);
// Kotlin
userList
// チームの重複を取り除く
.map { e: User -> e.team }
.distinct()
.forEach { s: String? -> print(s) }
// teamA teamB
sorted
sortedは、リスト の要素を並び替えるメソッドです。
// Java
userList.stream()
// スコアの降順→IDの昇順でソート
.sorted(Comparator.comparing(User::getScore).reversed().thenComparing(User::getId)) .forEach(System.out::print);
// Kotlin
userList
// スコアの降順→IDの昇順でソート
.sortWith(Comparator {
a: User,b: User -> b.score.compareTo(a.score)
})
userList
.forEach { obj: User -> print(obj) }
// user2 user4 user1 user3
take
takeは、リスト の先頭から指定した位置までを取り出すメソッドです。
// Java
userList.stream()
// 先頭から3つだけに絞る
.limit(3)
.forEach(System.out::print);
// Kotlin
userList
// 先頭から3つだけに絞る
.take(3)
.forEach { obj: User -> print(obj) }
// user1 user2 user3
drop
dropは、リスト の指定した位置から最後までを取り出すメソッドです。
// Java
userList.stream()
// 2番目以降に絞る
.skip(1)
.forEach(System.out::print);
// Kotlin
userList
// 2番目以降に絞る
.drop(1)
.forEach { obj: User -> print(obj) }
// user2 user3 user4
toMap
toMapは、リストを Map クラスに変換します。
// Java
Map<Integer, User> userMap = userList.stream()
.collect(Collectors.toMap(User::getId, e -> e));
println(userMap)
// Kotlin
val userMap = userList
.map { e -> e.id to e }.toMap()
println(userMap)
// {1=user1 , 2=user2 , 3=user3 , 4=user4 }
groupBy
groupBy は、リストを グループごとに分別します。
// Java
Map<String, List<User>> groupMap = userList.stream().collect(
Collectors.groupingBy(User::getTeam));
println(groupMap)
// Kotlin
val groupMap = userList.groupBy({ it.team }, { it })
println(groupMap)
// {teamA=[user1 , user3 ], teamB=[user2 , user4 ]}
count
count は、リスト の件数を取得するメソッドです。
// Java
long conut = userList.stream().count();
println(conut)
// Kotlin
val conut = userList.count()
println(conut)
// 4
max
max は、リスト の最大値 を取得するメソッドです。
// Java
Optional value = userList.stream()
.map(e -> e.getScore())
// 最大のスコアを取得
.max(Comparator.naturalOrder());
println(value)
// Kotlin
val value = userList
.map{it.score}
// 最大のスコアを取得
.maxOrNull()
println(value)
// 50
min
min は、リスト の最小値 を取得するメソッドです。
// Java
Optional value = userList.stream()
.map(e -> e.getScore())
// 最小のスコアを取得
.min(Comparator.naturalOrder());
// Kotlin
val value = userList
.map{it.score}
// 最小のスコアを取得
.minOrNull()
println(value)
// 10
sum
sum は、リスト の合計値を取得するメソッドです。
// Java
long sum = userList.stream()
.mapToLong(e -> e.getScore())
// 合計のスコアを取得
.sum();
// Kotlin
val sum = userList
.map { e: User -> e.score.toLong() }
// 合計のスコアを取得
.sum()
println(sum)
// 130
average
average は、リスト の平均値を取得するメソッドです。
// Java
OptionalDouble average = userList.stream()
.mapToLong(e -> e.getScore())
// スコアの平均を取得
.average();
// Kotlin
val average = userList
.map { e: User -> e.score.toLong() }
.average()
println(average)
// 32.5