采用各种类型的各种参数并在函数Java中返回某些对象的函数

时间:2017-11-01 16:32:26

标签: java lambda functional-programming

我们说我有一些lambda表达式如下:

        Function<String, List<String>> flines = fileName -> {
    //Puts all lines from file into List and returns a list
        };

        Function<List<String>, String> join = listOfLines -> {
    //Concatenates all lines from list and returns them as String
        };

        Function<String, List<Integer>> collectInts = str -> {
    //Returns all Integer occurences from given String
        };

我想创建一个函数,让我们说resultType convertBy(Function<T,S>...args) 所以我可以组合参数并返回结果:

List<String> lines = fileConv.convertBy(flines) //returns list of lines
String text = fileConv.convertBy(flines, join); //returns s String from concatenated Strings
List<Integer> ints = fileConv.convertBy(flines, join, collectInts); //returns list of Integers from string
Integer sumints = fileConv.convertBy(flines, join, collectInts, sum); ////returns list of Integers from string and sums it

用Java做某种可能吗?

编辑:我可以使用重载

1 个答案:

答案 0 :(得分:2)

使用泛型时,需要声明所涉及的类型变量。由于使用可变数量的泛型函数(使用varargs)定义链调用的方法将需要可变数量的类型变量,这是不可能的。

在编译时,不可能保证varargs给出的每个函数都使用类型,以便在链接调用时它们是兼容的。 你可以这样做,但不是以类型安全的方式。如果函数的输入/输出类型不匹配,将在运行时产生ClassCastException

private static <T, U> U convertBy(T arg, Function... functions) {
  Object result = arg;
  for (Function f : functions) {
    result = f.apply(result);
  }
  return (U) result;
}

@Test
public void test() {
  Function<String, Integer> f1 = s -> s.length();
  Function<Integer, Double> f2 = i -> i*2.0;
  Double d = convertBy("test", f1, f2);
  assertThat(d).isEqualTo(8.0);
}

但是,您可以手动定义该方法的变体,通过重载来完成链接:

private static <T, U> U convertBy(T arg, Function<T, U> func1) {
  return func1.apply(arg);
}

private static <T, U, V> V convertBy(T arg, Function<T, U> func1, Function<U, V> func2) {
  return func2.apply(func1.apply(arg));
}

private static <T, U, V, X> X convertBy(T arg, Function<T, U> func1, Function<U, V> func2, Function<V, X> func3) {
  return func3.apply(func2.apply(func1.apply(arg)));
}