在Java中,是否有可能让一个lambda接受多种不同的类型?

即: 单变量有效:

    Function <Integer, Integer> adder = i -> i + 1;
    System.out.println (adder.apply (10));

可变参数也可以工作:

    Function <Integer [], Integer> multiAdder = ints -> {
        int sum = 0;
        for (Integer i : ints) {
            sum += i;
        }
        return sum;
    };

    //.... 
    System.out.println ((multiAdder.apply (new Integer [] { 1, 2, 3, 4 })));

但我想要一些可以接受许多不同类型的参数,例如:

    Function <String, Integer, Double, Person, String> myLambda = a , b, c, d->  {
    [DO STUFF]
    return "done stuff"
    };

它的主要用途是在函数中加入小的内联函数以方便使用。

我已经环顾谷歌和检查Java的函数包,但不能找到。这可能吗?


当前回答

在这种情况下,你可以使用默认库(java 1.8)中的接口:

java.util.function.BiConsumer
java.util.function.BiFunction

有一个小的(不是最好的)例子默认方法在接口:

default BiFunction<File, String, String> getFolderFileReader() {
    return (directory, fileName) -> {
        try {
            return FileUtils.readFile(directory, fileName);
        } catch (IOException e) {
            LOG.error("Unable to read file {} in {}.", fileName, directory.getAbsolutePath(), e);
        }
        return "";
    };
}}

其他回答

另一种选择,不确定这是否适用于你的特定问题,但对一些可能适用的是在java.util.function库中使用UnaryOperator。 它返回你指定的相同类型,所以你把所有的变量放在一个类中,它是一个参数:

public class FunctionsLibraryUse {

    public static void main(String[] args){
        UnaryOperator<People> personsBirthday = (p) ->{
            System.out.println("it's " + p.getName() + " birthday!");
            p.setAge(p.getAge() + 1);
            return p;
        };
        People mel = new People();
        mel.setName("mel");
        mel.setAge(27);
        mel = personsBirthday.apply(mel);
        System.out.println("he is now : " + mel.getAge());

    }
}
class People{
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

因此,您拥有的类,在本例中是Person,可以有许多实例变量,并且不必更改lambda表达式的参数。

对于那些感兴趣的人,我已经写了关于如何使用java.util.function库的说明:http://sysdotoutdotprint.com/index.php/2017/04/28/java-util-function-library/

我认为我们可以将map作为参数传递,并将不同的值作为map的元素传递。

Function <Map <String, Object>, Integer> multiAdder = i -> {
    String  param1 = (String)i.get("PARAM1");
    Integer param2 = (Integer)i.get("PARAM2");
    Double  param3 = (Double)i.get("PARAM3");

    Integer x = callAnotherMethod(param1, param2, param3);
    return x;
};

//.... 
Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("PARAM1", "String Val");
paramsMap.put("PARAM2", new Integer(12));
paramsMap.put("PARAM3", new Double(45);
System.out.println ((multiAdder.apply (paramsMap )));

在这种情况下,你可以使用默认库(java 1.8)中的接口:

java.util.function.BiConsumer
java.util.function.BiFunction

有一个小的(不是最好的)例子默认方法在接口:

default BiFunction<File, String, String> getFolderFileReader() {
    return (directory, fileName) -> {
        try {
            return FileUtils.readFile(directory, fileName);
        } catch (IOException e) {
            LOG.error("Unable to read file {} in {}.", fileName, directory.getAbsolutePath(), e);
        }
        return "";
    };
}}

使用lambda:有三种类型的操作: 1. 接受参数——>消费者 2. 测试参数返回boolean——>谓词 3.操作参数和返回值——>函数

Java功能接口最多可达两个参数: 单参数接口 消费者 谓词 函数 双参数接口 BiConsumer BiPredicate BiFunction

对于两个以上的,你必须创建如下的功能接口(消费者类型):

@FunctionalInterface
public interface FiveParameterConsumer<T, U, V, W, X> {
    public void accept(T t, U u, V v, W w, X x);
}

如果用多个类型参数定义这样的功能接口,这是可能的。没有这样的内置类型。(有一些具有多个参数的有限类型。)

@FunctionalInterface
interface Function6<One, Two, Three, Four, Five, Six> {
    public Six apply(One one, Two two, Three three, Four four, Five five);
}

public static void main(String[] args) throws Exception {
    Function6<String, Integer, Double, Void, List<Float>, Character> func = (a, b, c, d, e) -> 'z';
}

我把它叫做Function6。名称由您自行决定,只是尽量不要与Java库中的现有名称冲突。


也没有办法定义变量数量的类型参数,如果这是您要问的。


一些语言,如Scala,定义了许多内置的此类类型,类型参数有1,2,3,4,5,6等。