article banner (priority)

Exercise: Adjust Kotlin for Java usage

Consider the following Kotlin elements:

package advanced.java data class Money( val amount: BigDecimal = BigDecimal.ZERO, val currency: Currency = Currency.EUR, ) { companion object { fun eur(amount: String) = Money(BigDecimal(amount), Currency.EUR) fun usd(amount: String) = Money(BigDecimal(amount), Currency.USD) val ZERO_EUR = eur("0.00") } } fun List<Money>.sum(): Money? { if (isEmpty()) return null val currency = this.map { it.currency }.toSet().single() return Money( amount = sumOf { it.amount }, currency = currency ) } operator fun Money.plus(other: Money): Money { require(currency == other.currency) return Money(amount + other.amount, currency) } enum class Currency { EUR, USD }

This is how they can be used in Kotlin:

fun main() { val money1 = Money.eur("10.00") val money2 = Money.eur("29.99") println(listOf(money1, money2, money1).sum()) // Money(amount=49.99, currency=EUR) println(money1 + money2) // Money(amount=39.99, currency=EUR) val money3 = Money.usd("10.00") val money4 = Money() val money5 = Money(BigDecimal.ONE) val money6 = Money.ZERO_EUR }

However, Java usage is not so convenient. Your task is to add appropriate annotations so it is more Java-friendly and can be used like this:

package advanced.java; import java.math.BigDecimal; import java.util.List; public class JavaClass { public static void main(String[] args) { Money money1 = Money.eur("10.00"); Money money2 = Money.eur("29.99"); List<Money> moneyList = List.of(money1, money2, money1); System.out.println(MoneyUtils.plus(money1, money2)); // Money(amount=39.99, currency=EUR) Money money3 = Money.usd("10.00"); Money money4 = new Money(); Money money5 = new Money(BigDecimal.ONE); Money money6 = Money.ZERO_EUR; } }

Once you are done with the exercise, you can check your solution here.