# Kotlin sum(), sumBy(), sumByDouble() and BigDecimal in List, Map example

In this Kotlin tutorial, I will show you some examples that uses `sum()`, `sumBy()`, `sumByDouble()` for List, Map. We’re gonna create `sum()` & `sumByBigDecimal()` which also work for List of `BigDecimal` objects.

## Kotlin sum()

The examples show you how to use sum() function to:

• sum of all items in the normal List
• sum of specific field in List of Objects (in need of `map()`)
• sum of specific field of all values in a Map (in need of `map()`)

Why we need `map()`?
`map()` will create a List of quantity first, then we invoke: `List<quantity>.sum()`

### List

We’re gonna use `sum()` on `List<Int>` and `List<Double>` for example.

``````val nums = listOf(10, 20, 30)
println(nums.sum())
// 60

val doubles = listOf(1.05, 2.05, 3.65)
println(doubles.sum())
// 6.75
``````

`sum()` function can also work with List of `Byte`, `Short`, `Long`, `Float` items.

### List of Objects

Now we will calculate total quantity of all Product(name, quantity, price) objects in List using `sum()`.

Bezkoder Programming Course

Now we create a simple data class `Product` like this.

``````package com.bezkoder.kotlin.sum

data class Product(val name: String, val quantity: Int, val price: Double) {
}
``````

Then we initialize `List<Product>` and we need to use `map()` to get the List of quantity objects before applying `sum()` on the result.

``````package com.bezkoder.kotlin.sum

fun main(args: Array<String>) {
val products = listOf(
Product("A", 10, 6.90),
Product("B", 20, 3.45),
Product("C", 30, 1.05)
)

val totalQuantity: Int = products.map { it.quantity }.sum()
println(totalQuantity)
// 60
}
``````

### Map

For `Map`, we also need to get the List of quantity objects before using `sum()`. It can be done with `map()` function.

``````val productsMap = mapOf(
"a" to Product("A", 10, 6.90),
"b" to Product("B", 20, 3.45),
"c" to Product("C", 30, 1.05)
)

val totalQuantity: Int = productsMap.map { it.value.quantity }.sum()
println(totalQuantity)
// 60
``````

## Kotlin sumBy()

The examples show you ways to use sumBy() function to:

• sum (and change value to `Int`) of all items in the normal List
• sum of specific `Int` field in List of Objects (no need `map()`)
• sum of specific `Int` field of all values in Map of Objects (no need `map()`)

Why we don’t need `map()`?
Look at protoype of `sumBy()` function:

``````inline fun sumBy(selector: (T) -> Int): Int
``````

You can see that `sumBy()` receives a `selector` which indicates the field to be processed.

### List

``````import kotlin.math.roundToInt

val nums = listOf(10, 20, 30)
println(nums.sumBy { it })
// 60
println(nums.sumBy { it * 2 })
// 120

val doubles = listOf(1.05, 2.05, 3.65)
println(doubles.sumBy { it.roundToInt() })
// 7
``````

`sumBy()` function can also work with List of `Byte`, `Short`, `Long`, `Float` items.

### List of Objects

Our work is simple now, just use `sumBy()` like this: `sumBy { it.quantity }`.

``````val products = listOf(
Product("A", 10, 6.90),
Product("B", 20, 3.45),
Product("C", 30, 1.05)
)

val totalQuantity: Int = products.sumBy { it.quantity }
println(totalQuantity)
// 60
``````

### Map

For `Map<String, Product>`, we use `map()` to get the List of `Product` objects before applying `sumBy()` on the result.

``````val productsMap = mapOf(
"a" to Product("A", 10, 6.90),
"b" to Product("B", 20, 3.45),
"c" to Product("C", 30, 1.05)
)

val totalQuantity: Int = productsMap.map { it.value }.sumBy { it.quantity }
println(totalQuantity)
// 60
``````

## Kotlin sumByDouble()

`sumBy()` always returns integer value. To work with `Double`, Kotlin provides sumByDouble() that calculate sum of all values produced by `selector` function applied to each item in the List.

``````inline fun sumByDouble(selector: (T) -> Double): Double
``````

The examples show you ways to use `sumByDouble()` function to:

• sum of all `Double` items in the normal List
• sum of specific `Double` field in List of Objects (no need `map()`)
• sum of specific `Double` field of all values in Map of Objects (no need `map()`)

### List

``````val doubles = listOf(1.05, 2.05, 3.65)

println(doubles.sumByDouble { it })
// 6.75

println(doubles.sumByDouble { it * 2 })
// 13.5
``````

### List of Objects

We’re gonna use `sumByDouble()` to get total price by calculating sum of (quantity * price) of each `Product` type.

``````val products = listOf(
Product("A", 10, 6.90),
Product("B", 20, 3.45),
Product("C", 30, 1.05)
)

val totalPrice: Double = products.sumByDouble { it.quantity * it.price }
println(totalPrice)
// 169.5
``````

### Map

``````val productsMap = mapOf(
"a" to Product("A", 10, 6.90),
"b" to Product("B", 20, 3.45),
"c" to Product("C", 30, 1.05)
)

val totalPrice: Double = productsMap.map { it.value }.sumByDouble { it.price * it.quantity }
println(totalPrice)
``````

## Kotlin sum() & sumBy() for List of BigDecimal

Assume that we have a List of BigDecimal objects like this.

``````import java.math.BigDecimal

val bigDecimals = listOf(
BigDecimal(124567890.0987654321),
BigDecimal(987654321.123456789),
BigDecimal(1122334455.66778899)
)
``````

If we use `sum()` function on the List: `bigDecimals.sum()`. What happens?

Compiler will show an error:
None of the following functions can be called with the arguments supplied

``````
None of the following functions can be called with the arguments supplied:
@JvmName public fun Iterable<Byte>.sum(): Int defined in kotlin.collections
@JvmName public fun Iterable<Double>.sum(): Double defined in kotlin.collections
@JvmName public fun Iterable<Float>.sum(): Float defined in kotlin.collections
@JvmName public fun Iterable<Int>.sum(): Int defined in kotlin.collections
@JvmName public fun Iterable<Long>.sum(): Long defined in kotlin.collections
@JvmName public fun Iterable<Short>.sum(): Int defined in kotlin.collections
@JvmName @SinceKotlin @ExperimentalUnsignedTypes public fun Iterable.sum(): UInt defined in kotlin.collections
@JvmName @SinceKotlin @ExperimentalUnsignedTypes public fun Iterable.sum(): UInt defined in kotlin.collections
@JvmName @SinceKotlin @ExperimentalUnsignedTypes public fun Iterable.sum(): ULong defined in kotlin.collections
``````

It’s because Kotlin doesn’t either provide `sum()` or `sumByBigDecimal()` for `BigDecimal` type. So we need to create the extension functions.

### sum() BigDecimal

Let’s make our `sum()` extension function like the following code.

``````fun Iterable<BigDecimal>.sum(): BigDecimal {
var sum: BigDecimal = BigDecimal.ZERO
for (element in this) {
sum += element
}
return sum
}
``````

Now you can use `bigDecimals.sum()` freely.

``````val bigDecimals = listOf(
BigDecimal(124567890.0987654321),
BigDecimal(987654321.123456789),
BigDecimal(1122334455.66778899)
)

println(bigDecimals.sum());
// 2234556666.890011250972747802734375
``````

### sumBy() BigDecimal

`sumByBigDecimal()` extension function will need a `selector`.

``````fun <T> Iterable<T>.sumByBigDecimal(selector: (T) -> BigDecimal): BigDecimal {
var sum: BigDecimal = BigDecimal.ZERO
for (element in this) {
sum += selector(element)
}
return sum
}
``````

Let’s run and check the result:

``````println(bigDecimals.sumByBigDecimal { it });
// 2234556666.890011250972747802734375
``````

If you create a `Foo` class with two fields: `name`, `value`.
This is how we use `sum()` & `sumByBigDecimal()` to work with List of `Foo` objects.

``````val foos = listOf(
Foo("A", BigDecimal(124567890.0987654321)),
Foo("B", BigDecimal(987654321.123456789)),
Foo("C", BigDecimal(1122334455.66778899))
)

println(foos.map { it.value }.sum());
// 2234556666.890011250972747802734375

println(foos.sumByBigDecimal { it.value });
// 2234556666.890011250972747802734375
``````

## Conclusion

Today we’re learned how to use `sum()`, `sumBy()`, `sumByDouble()` and `sumByBigDecimal()` for List, List of Objects & Map.

Let me summarize all of them.

• `sum()`: works for almost simple List with number types, but needs `map()` function to work with List of custom Objects.
• `sumBy()`: always returns `Int` value, has `selector` parameter so no need of `map()` function.
• `sumByDouble()`: like `sumBy()` but always returns `Double` value.
• `BigDecimal`: Kotlin doesn’t support, need to create `sum()` & `sumByBigDecimal()` extension functions.

## 4 thoughts to “Kotlin sum(), sumBy(), sumByDouble() and BigDecimal in List, Map example”

1. Luke Dutton says:

when I tried adding the Iterable.sum() function, I was getting an error that it was expecting a type for the iterable.

I fixed it by doing the following
“`
fun Iterable.sum(): BigDecimal {
var sum: BigDecimal = BigDecimal.ZERO
for (element in this) {
sum += element
}
return sum
}
“`

1. bezkoder says:

Oh yeah, it’s just a typo because of syntax highlighter plugin which needs ‘<‘ for ‘<', I've fixed:

``````fun Iterable<BigDecimal>.sum(): BigDecimal {
var sum: BigDecimal = BigDecimal.ZERO
for (element in this) {
sum += element
}
return sum
}
``````

Thanks for your comment to notify me ðŸ™‚

2. Ahmet says:

Thanx for helping. This text document very helpfull.