在Java中创建将数组和函数作为输入的map函数

时间:2018-10-10 17:39:01

标签: java java-8

我希望在Java中创建一个函数,该函数将一个不同的函数和一个数组作为输入,并输出一个数组,原始数组中的每个元素都已通过输入函数运行。

我得到的分配表示它希望map函数具有以下签名。

public static <R, D> R[] map(Function<R, D> function, D[] array)

该作业还提供了一些示例,由于该站点尚未允许我提供屏幕截图,因此我将其复制为以下示例。

// Example 1
Function<Integer, Integer> function = new CalculateSuccessor();
Integer[] integerArray = {1, 3, 4, 2, 5};
PrintArray(map(function, integerArray)); // map returns {2, 4, 5, 3, 6}

// Example 2
Function<Integer, String> anotherFunction = new CalculateLength();
String[] stringArray = { "Java", "C++", "Smalltalk" };
PrintArray(map(anotherFunction, stringArray)); // map returns {4, 3, 9}

// Example 3
Function<Double, Double> tripleFunction = new CalculateTriple();
Double[] doubleArray = { 2.0, 4.0, 5.0, 1.0 };
PrintArray(map(tripleFunction, doubleArray)); // map returns {6.0, 12.0, 15.0, 3.0}

在此先感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

不幸的是,赋值是错误的,因为必须将Function声明为Function<D, R> function,将其读为“从D转换为R的函数”。实际上,实现这种方法很简单:

@SuppressWarnings("unchecked")
public static <R, D> R[] map(Function<D, R> function, D[] array) {
    return (R[]) Arrays.stream(array)
            .map(function)
            .toArray(Object[]::new);
}

一个小警告。不允许在Java中创建通用数组,但必须声明一个,并且数组也是 covariant ,这意味着您可以将一个分配给另一个,例如,不同于通用。您将如何使用方法的一个示例是:

public static void main(String[] args) {
    System.out.println(Arrays.toString(map(x -> x + 1, new Integer[] { 1, 2, 3 })));
}

编辑

阅读下面的迪迪埃评论,基本上上面写的是错误的,我将其留作学习之用(包括我在这里的失败)。您可以这样做,但是需要向该方法传递一个附加参数,例如:

public static <R, D> R[] map(Function<D, R> function, D[] array, IntFunction<R[]> func) {
    return Arrays.stream(array)
            .map(function)
            .toArray(func);
}

这很像ReferencePipeline::toArray

另一种选择是返回Object[],然后使用Arrays::copyOf

public static <R, D> Object[] map(Function<D, R> function, D[] array) {
    return Arrays.stream(array)
            .map(function)
            .toArray();
}

Integer[] input = { 1, 2, 3, 4 };
Object[] obj = map(x -> x + 1, input);
Integer[] result = Arrays.copyOf(obj, obj.length, Integer[].class);