Kotlin:列表中BigDecimal的总和

Kotlin:列表中BigDecimal的总和,kotlin,Kotlin,我有一个要筛选的列表,然后返回一个包含金额总和的id映射: val totalById = list .filter { it.status == StatusEnum.Active } .groupBy { it.item.id } .mapValues { it.value.sumBy { it.amount } } “it.amount”是BigDecimal,但看起来

我有一个要筛选的列表,然后返回一个包含金额总和的id映射:

val totalById = list
                    .filter { it.status == StatusEnum.Active }
                    .groupBy { it.item.id }
                    .mapValues { it.value.sumBy { it.amount } }
“it.amount”是BigDecimal,但看起来sumBy只是Int

对于java 8,它应该是:

Collectors.groupingBy(i->i.getItem().getId(),Collectors.mapping(Item::getAmount,Collectors.reduced(BigDecimal.ZERO,BigDecimal::add)))


在Kotlin中有没有办法做到这一点?

您可以创建自己的
sumByBigDecimal
类似于。e、 g:


就像您使用的
收集器一样。在java中减少
,您可以在Kotlin中使用
折叠
减少
扩展函数:

val bigDecimals: List<BigDecimal> = ...
val sum = bigDecimals.fold(BigDecimal.ZERO) { acc, e -> acc + e }
// or
val sum2 = bigDecimals.fold(BigDecimal.ZERO, BigDecimal::add)

play.kotlinlang.org上的完整示例:

结合折叠方法和扩展函数方法,您可以执行以下操作:

fun Iterable<BigDecimal>.sumByBigDecimal(): BigDecimal {
    return this.fold(BigDecimal.ZERO) { acc, e -> acc + e }
}

fun <T> Iterable<T>.sumByBigDecimal(transform: (T) -> BigDecimal): BigDecimal {
    return this.fold(BigDecimal.ZERO) { acc, e -> acc + transform.invoke(e) }
}

如果列表不是空的,您也可以使用
reduce

val bigDecimals: List<BigDecimal> = ...
val sum = bigDecimals.reduce(BigDecimal::add)
val bigDecimals:List=。。。
val sum=bigDecimals.reduce(BigDecimal::add)

如果列表可以为空,则您需要
折叠
大十进制.ZERO
,就像公认的答案所建议的那样。

在Kotlin 1.4中,他们介绍了
sumOf
,它的用法:

val bigDecimals: List<BigDecimal> = ...
val sum = bigDecimals.sumOf { it }
val bigDecimals:List=。。。
val sum=bigDecimals.sumOf{it}

有没有办法使内联函数成为全局函数?正如您所看到的,这个sumByBigDecimal用于整个应用程序。该函数默认为全局@klc。它可以在任何地方导入和使用。我尝试过:.mapValues{It.value.map{It.amount}.fold(BigDecimal.ZERO,BigDecimal::add),但编译器抱怨:::add::以下函数都不能使用提供的参数调用:[错误]private open fun add(p0:BigInteger!,p1:Int,p2:BigInteger!,p3:Int):BigDecimal!在java.math.BigDecimal[ERROR]private open fun add中定义(p0:Long,p1:Int,p2:biginger!,p3:Int):BigDecimal!在java.math.BigDecimal[ERROR]private open fun add中定义(p0:Long,p1:Int,p2:Long,p3:Int):BigDecimal!在java.math.BigDecimal[ERROR]private open fun add:Long中定义:在java.math.BigDecimal[ERROR]private open fun add中定义的Long(p0:Long,p1:Long,p2:Int):BigDecimal!在java.math中定义。BigDecimal@klc,我已经制作了一个完整的示例,它是有效的:,您可以自己在那里尝试。感谢这个示例,我无法用intellij编译它…我会研究它…第一种方法有效!这应该是正确/最好的答案!谢谢。
fun Iterable<BigDecimal>.sumByBigDecimal(): BigDecimal {
    return this.fold(BigDecimal.ZERO) { acc, e -> acc + e }
}

fun <T> Iterable<T>.sumByBigDecimal(transform: (T) -> BigDecimal): BigDecimal {
    return this.fold(BigDecimal.ZERO) { acc, e -> acc + transform.invoke(e) }
}
listOfBigs.sumByBigDecimal()

listOfWidgets.sumByBigDecimal { it.price }
val bigDecimals: List<BigDecimal> = ...
val sum = bigDecimals.reduce(BigDecimal::add)
val bigDecimals: List<BigDecimal> = ...
val sum = bigDecimals.sumOf { it }