创建一个接受具有可能不同类型的可变长度的Function参数的方法 [英] Create a method that accepts variable length of Function arguments with possibly different types

查看:87
本文介绍了创建一个接受具有可能不同类型的可变长度的Function参数的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这些函数可能有不同的< T,U> 类型。



这样一个函数的例子如下:

 结合<字符串> c =新的Combine<>(s); 
列表< String> numbers = c.combineFunctions(splitByComma);
Integer max = c.combineFunctions(splitByComma,convertToInt,findMax);

我试过的(< U>

  public< U> void combineFunctions(
Function< ;? extends Object,?extends Object> ... functions){

}

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



有可能在Java中实现此类方法吗?

解决方案

这个函数的问题在于,你放弃了所有编译时类型检查,并且必须进行转换。



这将是一个实现,使用和Then 将函数组合在一起。这看起来很丑,因为所有的演员,我不知道你可以做得更好。

  public static void main(String []] args)抛出Exception {
String str =1,2,3,4,5,6;
函数< Object,Object> splitByComma = s - > ((String)s).split(,);
函数< Object,Object> convertToInt =令牌 - > Stream.of((String [])tokens).map(Integer :: valueOf).toArray(Integer [] :: new);
函数< Object,Object> 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< Object,Object> combineFunctions(Function< Object,Object> ... functions){
return Arrays.stream(functions)
.reduce(Function :: andThen)
.orElseThrow(( - ) - > new IllegalArgumentException(无功能组合));

$ / code $ / pre


$ b

匹配代码你的问题,你可以把它包装成这样的类:

  public class Combiner< R> {

私人对象输入;

公共组合器(对象输入){
this.input = input;

$ b @SuppressWarnings(unchecked)
@SafeVarargs
public final R combineFunctions(Function< Object,Object> ... functions){
)return(R)Arrays.stream(functions)
.reduce(Function :: andThen)
.orElseThrow(() - > new IllegalArgumentException(No functions to combine))
。适用(输入);
}

}


Suppose I have a string: String s = "1,2,3,4,5,6". I would like to create a method combineFunctions() that would take a variable length sequence of Functions as an argument and apply all of the operations in that order.

The functions may have different <T,U> types.

Example uses of such a function would be the following:

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

What I have tried (the <U> here is not of much use here):

public <U> void combineFunctions(
        Function<? extends Object, ? extends Object>... functions) {

}

But I am stuck at getting type of last one of the Functions. I was also thinking about a recursive approach but the varargs parameter has to be the last one.

Would it be possible to implement such method in Java?

解决方案

The problem with such a function is that you loose all compile-time type checking and casting is necessary.

This would be an implementation, using andThen to combine functions together. This looks ugly because of all the casting and I'm not sure you can do it more properly. Notice also that this requires the creation of 2 Stream pipelines when only 1 is really necessary.

public static void main(String[] args) throws Exception {
    String str = "1,2,3,4,5,6";
    Function<Object, Object> splitByComma = s -> ((String) s).split(",");
    Function<Object, Object> convertToInt = tokens -> Stream.of((String[]) tokens).map(Integer::valueOf).toArray(Integer[]::new);
    Function<Object, Object> 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<Object, Object> combineFunctions(Function<Object, Object>... functions) {
    return Arrays.stream(functions)
                 .reduce(Function::andThen)
                 .orElseThrow(() -> new IllegalArgumentException("No functions to combine"));
}


To match the code in your question, you could wrap this into a class like this:

public class Combiner<R> {

    private Object input;

    public Combiner(Object input) {
        this.input = input;
    }

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

}

这篇关于创建一个接受具有可能不同类型的可变长度的Function参数的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆