Java Lambda可以有多个参数吗?


157

在Java中,lambda是否可以接受多种不同类型?

即:单个变量起作用:

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

Varargs也可以工作:

    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"
    };

为了方便起见,主要用途是在函数内部具有小的内联函数。

我环顾了Google并检查了Java的Function Package,但找不到。这可能吗?

Answers:


178

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

@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等类型参数定义了许多内置类型。


58
您可以随时使用Currying:Function<One, Function<Two, Function<Three, Function<Four, Function<Five, Six>>>>> func = a -> b -> c -> d -> e -> 'z';
Holger

@SotiriosDelimanolis:我宁愿选择一个Function与之冲突的名称,java.util.function.Function<T,R>对于初学者来说可能不清楚。
尼古拉斯

@Nikolas这是合理的。编辑。
Sotirios Delimanolis

39

对于带有2个参数的东西,您可以使用BiFunction。如果需要更多,可以定义自己的功能接口,如下所示:

@FunctionalInterface
public interface FourParameterFunction<T, U, V, W, R> {
    public R apply(T t, U u, V v, W w);
}

如果有多个参数,则需要在参数列表周围加上括号,如下所示:

FourParameterFunction<String, Integer, Double, Person, String> myLambda = (a, b, c, d) -> {
    // do something
    return "done something";
};

34

在这种情况下,您可以使用默认库(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 "";
    };
}}

5
如果您修改问题来说明如何使用这些接口来满足要求,您将获得Java8爱好者的更多支持。
Martin Cowie

3
BiFunction允许您仅定义两个参数的函数,问题是关于具有任意数量的参数的函数
Dmitry Klochkov

8

要使用lambda,请执行以下三种操作:
1.接受参数->使用者
2.测试参数返回布尔值->谓词
3.操纵参数和返回值->函数

Java Functional接口,最多两个参数:
单参数接口
Consumer
Predicate
Function

两个参数接口
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);
}

1

不确定这是否适用于您的特定问题但可能适用于某些特定问题的另一种替代方法是UnaryOperator在java.util.function库中使用。它返回指定的相同类型,因此将所有变量都放在一个类中,并将其作为参数:

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/


1

您还可以使用jOOL库-https: //github.com/jOOQ/jOOL

它已经准备了带有不同数量参数的功能接口。例如,你可以使用org.jooq.lambda.function.Function3,等从Function0可达Function16

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.