创建一个方法,接受可变长度的Function参数,可能有不同的类型

假设我有一个字符串: String s = "1,2,3,4,5,6" 。 我想创建一个方法combineFunctions() ,它将Function s的可变长度序列作为参数,并按该顺序应用所有操作。

这些函数可能有不同的类型。

这种function的示例用法如下:

 Combine c = new Combine(s); List numbers = c.combineFunctions(splitByComma); Integer max = c.combineFunctions(splitByComma,convertToInt, findMax); 

我尝试了什么(这里的在这里没什么用处):

 public  void combineFunctions( Function... functions) { } 

但我坚持要获得Function的最后一个类型。 我也在考虑递归方法,但varargs参数必须是最后一个。

是否有可能在Java中实现这样的方法?

这样一个函数的问题是你必须松开所有编译时类型检查和转换。

这将是一个实现,使用和andThen将function组合在一起。 由于所有的铸造,这看起来很丑陋,我不确定你能做得更好。 另请注意,当只需要1时,这需要创建2个流管道。

 public static void main(String[] args) throws Exception { String str = "1,2,3,4,5,6"; Function splitByComma = s -> ((String) s).split(","); Function convertToInt = tokens -> Stream.of((String[]) tokens).map(Integer::valueOf).toArray(Integer[]::new); Function findMax = ints -> Stream.of((Integer[]) ints).max(Integer::compare).get(); Integer max = (Integer) combineFunctions(splitByComma, convertToInt, findMax).apply(str); System.out.println(max); } @SafeVarargs private static Function combineFunctions(Function... functions) { return Arrays.stream(functions) .reduce(Function::andThen) .orElseThrow(() -> new IllegalArgumentException("No functions to combine")); } 

要匹配您问题中的代码,您可以将其包装到这样的类中:

 public class Combiner { private Object input; public Combiner(Object input) { this.input = input; } @SuppressWarnings("unchecked") @SafeVarargs public final R combineFunctions(Function... functions) { return (R) Arrays.stream(functions) .reduce(Function::andThen) .orElseThrow(() -> new IllegalArgumentException("No functions to combine")) .apply(input); } } 

通过使用function风格的Streams ,您的问题中的示例很容易解决。 解决这个问题的“function”方法是使用map操作序列,每个步骤将元素转换为不同的类型,然后可选地减少/收集结果。

例如

 String str = "1,2,3,4,5,6,7"; int max = Arrays.stream(str.split(",")).mapToInt(Integer::parseInt).max().orElse(0) 

相同的模式适用于其他类型的“function组合”。