What Java 8 Stream.collect equivalents are available in the standard Kotlin library?

后端 未结 4 1784
礼貌的吻别
礼貌的吻别 2020-11-27 09:05

In Java 8, there is Stream.collect which allows aggregations on collections. In Kotlin, this does not exist in the same way, other than maybe as a collection of extension f

4条回答
  •  隐瞒了意图╮
    2020-11-27 09:23

    More on laziness

    Let's take the example solution for "Compute sum of salaries by department" given by Jayson:

    val totalByDept = employees.groupBy { it.dept }.mapValues { it.value.sumBy { it.salary }}
    

    In order to make this lazy (i.e. avoid creating an intermediate map in the groupBy step), it is not possible to use asSequence(). Instead, we must use groupingBy and fold operation:

    val totalByDept = employees.groupingBy { it.dept }.fold(0) { acc, e -> acc + e.salary }
    

    To some people this may even be more readable, since you're not dealing with map entries: the it.value part in the solution was confusing for me too at first.

    Since this is a common case and we'd prefer not to write out the fold each time, it may be better to just provide a generic sumBy function on Grouping:

    public inline fun  Grouping.sumBy(
            selector: (T) -> Int
    ): Map = 
            fold(0) { acc, element -> acc + selector(element) }
    

    so that we can simply write:

    val totalByDept = employees.groupingBy { it.dept }.sumBy { it.salary }
    

提交回复
热议问题