Reputation: 318
I have the Kotlin object declaration bellow, with a detected smell (duplicate code)
object Random {
internal fun generatePositiveFloat(
leftLimit: Float = Float.MIN_VALUE,
rightLimit: Float = Float.MAX_VALUE
): Float {
if (leftLimit < 0) {
throw InvalidAlgorithmParameterException("
Left limit can't be negative"
)
} else if (rightLimit <= leftLimit) {
throw InvalidAlgorithmParameterException(
"Right limit can't be less or equal than left limit"
)
}
return Random().nextFloat()
}
internal fun generatePositiveShort(
leftLimit: Short = 0,
rightLimit: Short = Short.MAX_VALUE
): Short {
if (leftLimit < 0) {
throw InvalidAlgorithmParameterException(
"Left limit can't be negative"
)
} else if (rightLimit <= leftLimit) {
throw InvalidAlgorithmParameterException(
"Right limit can't be less or equal than left limit"
)
}
return ThreadLocalRandom.current().nextInt(
leftLimit.toInt(),
rightLimit.toInt()
).toShort()
}
Any idea for taking out this duplicate code to a private function?
My idea is something like this...
private fun validatePositiveLimits(
leftLimit: Number,
rightLimit: Comparable<Number>) {
if (leftLimit as Comparable<Number> < 0) {
throw InvalidAlgorithmParameterException(
"Left limit can't be negative"
)
} else if (rightLimit <= leftLimit) {
throw InvalidAlgorithmParameterException(
"Right limit can't be less or equal than left limit"
)
}
}
... but I'm having trouble comparing leftLimit with 0 (leftLimit as Comparable < 0).
I get ClassCastException trying to cast integer to short and trying to cast integer to float.
Thanks so much.
Upvotes: 2
Views: 148
Reputation: 81879
Some simple generics can provide a solution here:
private fun <T : Comparable<T>> checkConditions(left: T, right: T, leftLowerBound: T) {
if (left < leftLowerBound) {
throw InvalidAlgorithmParameterException(
"Left limit can 't be negative"
)
} else if (right <= left) {
throw InvalidAlgorithmParameterException(
"Right limit can't be less or equal than left limit"
)
}
}
Invoked like this for Float:
checkConditions(leftLimit, rightLimit, 0F)
And like this for Short:
checkConditions(leftLimit, rightLimit, 0.toShort())
Upvotes: 2
Reputation: 11849
You can pass in 0
as an explicit argument.
private fun <T> validatePositiveLimits(zero: T, left: T, right: T) where T : Number, T : Comparable<T> {
if (left < zero) {
throw IllegalArgumentException("Left limit can't be negative")
} else if (right <= left) {
throw IllegalArgumentException("Right limit can't be less or equal than left limit")
}
}
Upvotes: 1