开发者

Java function for int[], float[] or double[] array

I want to write 开发者_Go百科a Java function that will get as input either int[], float[] or double[]. The algorithm is exactly the same (some kind of a scalar product). How can I write a single function that will be able to handle all types of numeric arrays?


There is no easy way to handle this in Java. You can:

  • Use Wrapper types (Integer[], Float[], Double[]) and have a function taking Number[] as an argument. Works since arrays are covariant in Java:

public static void main(String[] args) {
    f(new Integer[]{1,2,3});
    f(new Float[]{1,2,3});
    f(new Double[]{1,2,3});
}

private static void f(Number[] numbers) {
    f[0].doubleValue();
}

Note that this approach increases memory consumption significantly.


  • Convert int[] and float[] arrays to double[] and work with doubles all along. Preferably create overloaded versions of your method where the ones taking int[] and float[] are only doing the conversion and delegate to actual double[] implementation.

  • I believe Scala can handle this seamlessly as Java primitive types are semantically objects in Scala.


You cannot code this in Java without either:

  • coding each case separately or,

  • using reflection for all operations on the array ... which is likely to be messy, fragile and an order of magnitude slower than an optimal solution.

The only common supertype of int[] float[] and double[] is Object, so there is no possibility of a solution using polymorphism over those types. Likewise, generics require that the type parameter is a reference type, and int, float and double are not reference types.

You either need to accept that you will have duplicate code, or change the representation type for the arrays; e.g. use Integer[] / Float[] / Double[] or Number[].


You can write one method to do them all, however, it won't be anywhere near as readable of efficient. You have to make a choice between what is a generic or an efficient solution.

public static void main(String... args) throws IOException {
    int[] nums = new int[10*1000 * 1000];
    {
        long start = System.nanoTime();
        product2(nums);
        long time = System.nanoTime() - start;
        System.out.printf("Took %.3f seconds to take the product of %,d ints using an int[].%n", time / 1e9, nums.length);
    }
    {
        long start = System.nanoTime();
        product(nums);
        long time = System.nanoTime() - start;
        System.out.printf("Took %.3f seconds to take the product of %,d ints using reflections.%n", time / 1e9, nums.length);
    }
}

public static double product(Object array) {
    double product = 1;
    for (int i = 0, n = Array.getLength(array); i < n; i++)
        product *= ((Number) Array.get(array, i)).doubleValue();
    return product;
}

public static double product2(int... nums) {
    double product = 1;
    for (int i = 0, n = nums.length; i < n; i++)
        product *= nums[i];
    return product;
}

prints

Took 0.016 seconds to take the product of 10,000,000 ints using an int[].
Took 0.849 seconds to take the product of 10,000,000 ints using reflections.

If you are only working on relatively small arrays, the generic but less efficient solution may be fast enough.


Use java.lang.Number type or Object parameter type.

For more info read Bounded Type Parameters


I see two options:

1) You can create a new class which allows int[], float[], double[] in the contructor and saves them.

2) You allow Object[] and check for int / float / double. (You have to convert them first)


class ArrayMath {
    private ArrayMath() {
    }

    public static <T extends Number> double ScalarProduct(T[] a, T[] b){
        double sum = 0;

        for(int i=0;i<a.length;++i){
            sum += a[i].doubleValue()*b[i].doubleValue();
        }
        return sum;
    }
}
class Sample {
    public static void main(String arg[]){
        Integer[] v1 = { 1, -10, 3, 9, 7, 99, -25 };
        Integer[] v2 = { 1, -10, 3, 9, 7, 99, -25 };
        double p_int = ArrayMath.ScalarProduct(v1, v2);
        Double[] v1_d = { 1.1, -10.5, 3.7, 9.98, 7.4, 9.9, -2.5 };
        Double[] v2_d = { 1.1, -10.5, 3.7, 9.98, 7.4, 9.9, -2.5 };
        Double p_double = ArrayMath.ScalarProduct(v1_d, v2_d);

        System.out.println("p_int:" + p_int);
        System.out.println("p_double:" + p_double);
    }
}


Hope this will help you.. I have tested this code and it does what you have asked for, how to implement this logic is upto you !

public class MultiDataType {

    public static void main(String[] args) {

        int[] i = new int[2];
        float[] f = new float[2];
        double[] d = new double[2];
        String str = new String();

        handlingFunction(i);
        handlingFunction(f);
        handlingFunction(d);
        handlingFunction(str);
    }

    public static void handlingFunction(Object o) {
        String classType = null;
        if (o.getClass().getCanonicalName().equals("int[]")) {
            classType = "int[]";// Your handling code goes here
        } else if (o.getClass().getCanonicalName().equals("float[]")) {
            classType = "float[]";// Your handling code goes here
        } else if (o.getClass().getCanonicalName().equals("double[]")) {
            classType = "double[]";// Your handling code goes here
        }else classType = o.getClass().getCanonicalName();

        System.out.println("Object belongs to " + classType);
    }

}

OUTPUT

Object belongs to int[]
Object belongs to float[]
Object belongs to double[]
Object belongs to java.lang.String
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜