繁体   English   中英

如何以通用方式使用算术运算来减少原始数组?

[英]How to reduce a primitive array using an arithmetic operation in a generic manner?

我有这个方法:

public static long[] computeDifferenceArray(long[] array) {
    long[] diffArray = new long[array.length - 1];
    for (int i = 0; i < diffArray.length; i++) {
        diffArray[i] = array[i + 1] - array[i];
    }

    return diffArray;
}

目前,它只接受long[]并返回一个long[] 但我也想在int[]上使用同样的方法。 我怎样才能做到这一点?

我读过 Java Generics 仅适用于 class 个对象。

你必须每次将你的 int[] 转换为 long[]。你可以试试这个,

公共 static void main(String[] args) {

    int[] a1=new int[] {1,2,3,4,5};
    Test1.computeDifferenceArray( Arrays.stream(a1).mapToLong(i -> i).toArray());
    System.out.println("56897");
}

public static Long[] computeDifferenceArray(long[] array) {
    Long[] diffArray = new Long[array.length - 1];
    for (int i = 0; i < diffArray.length; i++) {
        diffArray[i] = array[i + 1] - array[i];
    }

    return diffArray;
}

实现您的要求的最佳方法是编写一个通用方法并注入要应用于数组成员的所需行为 - 如果需要,可以实现策略模式。 随着流的引入,您可以非常优雅地做到这一点,请按照以下给定方式重写您的代码:

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;

import static junit.framework.TestCase.assertEquals;

// The logic context
class ArrayDifference {
    public <T> List<T> difStream(T[] input, BiFunction<T,T,T> operation) {
        List<T> output = new ArrayList<>();

        for (int i=0; i < input.length-1; i++) {
            output.add(operation.apply(input[i], input[i+1]));
        }

        return output;
   }
}

// additional reducing functions
class Reducers {
    static float substract(float f1, float f2) {
        return f1-f2;
    }

    static double substract(double d1, double d2) {
        return d1-d2;
    }
}

public class ArrayDifferenceTest {

    ArrayDifference arraySubstracter = new ArrayDifference();

    @Test
    public void test_integer() {
        Integer[] input = new Integer[]{Integer.valueOf(1), 
Integer.valueOf(2), Integer.valueOf(3)};
        List<Integer> expectedResult = Arrays.asList(-1,-1);

        // here you can see how it is called for integer
        List<Integer> result = arraySubstracter.difStream(input, Math::subtractExact);

        assertEquals(expectedResult, result);
    }

    @Test
    public void test_long() {
        Long[] input = new Long[]{Long.valueOf(1), Long.valueOf(2), Long.valueOf(3)};
        List<Long> expectedResult = Arrays.asList(-1L,-1L);;

        // here you can see how it is called for long
        List<Long> result = arraySubstracter.difStream(input, Math::subtractExact);

        assertEquals(expectedResult, result);
    }

    @Test
    public void test_double() {
        Double[] input = new Double[]{Double.valueOf(1), Double.valueOf(2), Double.valueOf(3)}
        List<Double> expectedResult = Arrays.asList(-1D,-1D);

        // here you can see how it is called for double
        List<Double> result = arraySubstracter.difStream(input, Reducers::substract);

        assertEquals(expectedResult, result);
    }


    @Test
    public void test_float() {
        Float[] input = {Float.valueOf(1F), Float.valueOf(2F), Float.valueOf(3F)};
        List<Float> expectedResult = Arrays.asList(-1F, -1F);

        // here you can see how it is called for float
        List<Float> result = arraySubstracter.difStream(input, Reducers::substract);

        assertEquals(expectedResult, result);
    }
}

可以看到,方法没有改变,从外部注入行为。 出于测试目的,我使用了 Math.substractExact() 方法,对于 float 和 double,我编写了简单的方法。 这样,代码是可扩展的,并且以后很容易添加新的数据类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM