I'm studying Kotlin and as part of learning it I want to design a class that would represent a rational number, requirements:
- Class should contain two immutable integer fields: numerator and denominator.
- Class should contain valid equals, hashCode and toString implementations.
- When class is initialized, numerator and denominator should be deleted by their GCD (it means that
Ratio(1, 2) == Ratio(2, 4 /* or 4, 8 */) or Ratio(2, 4 /* or 4, 8 */).numerator == 1, .denominator == 2etc.) - This class should contain mul method that takes another Ratio and returns multiplication result of the current ratio and the given one.
I tried to use data classes what looked suitable for that task, but I was stuck with inability to define a custom constructor (both numerator and denominator need to be deleted to their GCD).
Possible solution:
class Ratio(num : Int, denom : Int) {
val numerator = num / gcd(num, denom)
val denominator = denom / gcd(num, denom) // GCD calculated twice!
}
What is the simplest way to define a class constructor so that GCD is calculated once?
UPDATE
OK, it looks like I found the possible solution:
data class Ratio(num : Int, denom : Int) {
val numerator : Int
val denominator : Int
{
val gcd = calcGcd(num, denom)
numerator = num / gcd
denominator = denom / gcd
}
}
but it renders that data qualifier useless - after this change Ratio class no longer has auto generated equals/hashCode/toString.
Verified on the latest version of Kotlin - 0.9.66
Program that reproduces that behavior:
data class Ratio(num : Int, denom : Int) {
val numerator : Int
val denominator : Int
{
val gcd = BigInteger.valueOf(num.toLong()).gcd(BigInteger.valueOf(denom.toLong())).intValue();
numerator = num / gcd;
denominator = denom / gcd
}
}
data class Ratio2(val num : Int, val denom : Int)
fun main(args: Array<String>) {
println("r = " + Ratio(1, 6).toString())
println("r2 = " + Ratio2(1, 6).toString())
}
output:
r = Ratio@4ac68d3e
r2 = Ratio2(num=1, denom=6)
that's clear that Ratio no longer has auto generated toString method
dataissue to JetBrains? Sounds like a bug