如何将类似的Java函数合并为一个(在C++中我使用模板)

Mar*_*com 6 java generics function

在我的一个Java类中,我有两个非常相似的函数.Java中有没有办法将它们组合成一个函数,所以我不需要维护2个函数?

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;
}
Run Code Online (Sandbox Code Playgroud)

eri*_*cbn 5

对于Java来说,你的问题在某些方面很棘手:

  1. double并且float是原始类型,因此它们不是类层次结构的一部分.包装器DoubleFloatNumber扩展Object,但是扩展了
  2. 原语类型的数组是不一样的对象的数组,和Java不autobox一float[]Float[],例如.
  3. Java API中没有isNan(Number n)或者没有isNan(Object o)方法,但是你使用的是那些期望a double或a的float.但是,你可以做Double.isNan(n.doubleValue())任何事情Number n.

TL; DR在Java中,原始类型的常见做法是为每个类型实现单独的实现,就像您一样.

编辑:正如@azurefrog建议:

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;
}
Run Code Online (Sandbox Code Playgroud)

然后你必须使用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);
}
Run Code Online (Sandbox Code Playgroud)

EDIT2: @ shmosel的解决方案将数组作为a传递Object,从那里避免将整个数组转换为盒装类型.值得考虑的解决方案,以避免这种开销.


shm*_*sel 4

这不是一个理想的场景,原因是@ericbn 解释的。但这里有一种使用 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;
}
Run Code Online (Sandbox Code Playgroud)