In one of my Java classes I have these 2 very similar functions. Is there a way in Java to combine them into one function so I don't have to maintain 2 functions?
public static boolean areValuesValid( double [] values, int numElements ) {
if( values == null || values.length != numElements ) {
return false;
}
for( int i = 0; i < numElements; ++i ) {
if( Double.isNaN( values[i] ) ) {
return false;
}
}
return true;
}
public static boolean areValuesValid( float [] values, int numElements ) {
if( values == null || values.length != numElements ) {
return false;
}
for( int i = 0; i < numElements; ++i ) {
if( Float.isNaN( values[i] ) ) {
return false;
}
}
return true;
}
Your question is tricky in some ways for Java:
double
and float
are primitive types, and as such they are not part of a class hierarchy. The wrapper Double
and Float
classes extends Number
, which extends Object
, butfloat[]
to Float[]
, for example.isNan(Number n)
or isNan(Object o)
method in the Java API, but the ones above that you used, that expect a double
or a float
. However, you can do Double.isNan(n.doubleValue())
for any Number n
.TL;DR In Java the common practice for primitive types is to have separate implementations for each one of them, like you did.
EDIT: As @azurefrog suggested:
public static boolean areValuesValid(Number[] values, int numElements) {
if (values == null || values.length != numElements) {
return false;
}
for (Number value : values) {
if (Double.isNaN(value.doubleValue())) {
return false;
}
}
return true;
}
And then you'd have to use Apache Commons ArrayUtils:
public static boolean areValuesValid(double[] values, int numElements) {
return areValuesValid(ArrayUtils.toObject(values), numElements);
}
public static boolean areValuesValid(float[] values, int numElements) {
return areValuesValid(ArrayUtils.toObject(values), numElements);
}
EDIT2: @shmosel's solution passes the array as an Object
and from there avoids the conversion of the whole array to a boxed type. A solution worth considering to avoid that overhead.
It's not an ideal scenario, for the reasons @ericbn explained. But here's one way to avoid most of the duplication using a lambda:
public static boolean areValuesValid( double [] values, int numElements ) {
return areValuesValid(values, numElements, i -> !Double.isNaN(values[i]));
}
public static boolean areValuesValid( float[] values, int numElements ) {
return areValuesValid(values, numElements, i -> !Float.isNaN(values[i]));
}
private static boolean areValuesValid( Object values, int numElements, IntPredicate tester ) {
if( values == null || Array.getLength(values) != numElements ) {
return false;
}
for( int i = 0; i < numElements; ++i ) {
if( !tester.test(i) ) {
return false;
}
}
return true;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With