Подтвердить что ты не робот

Может ли jamba jambda иметь более одного параметра?

В Java, возможно ли иметь лямбда принять несколько разных типов?

Т.е.: работает одна переменная:

    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, но не смог найти. Это возможно?

4b9b3361

Ответ 1

Возможно, если вы определите такой функциональный интерфейс с несколькими параметрами типа. Нет такого встроенного типа. (Существует несколько ограниченных типов с несколькими параметрами.)

@FunctionalInterface
interface Function<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 {
    Function<String, Integer, Double, Void, List<Float>, Character> func = (a, b, c, d, e) -> 'z';
}

Также нет способа определить переменное количество параметров типа, если это то, о чем вы просили.


Некоторые языки, такие как Scala, определяют количество встроенных таких типов, с параметрами типа 1, 2, 3, 4, 5, 6 и т.д.

Ответ 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";
};

Ответ 3

В этом случае вы можете использовать интерфейсы из библиотеки по умолчанию (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 "";
    };
}}

Ответ 4

Еще одна альтернатива, неясно, относится ли это к вашей конкретной проблеме, но для некоторых она может быть применима, чтобы использовать UnaryOperator в библиотеке java.util.function. где он возвращает тот же тип, который вы указываете, поэтому вы помещаете все свои переменные в один класс и является ли это параметром:

public class FunctionsLibraryUse {

    public static void main(String[] args){
        UnaryOperator<People> personsBirthday = (p) ->{
            System.out.println("it " + 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, может иметь множество переменных экземпляра и не должен будет изменять параметр вашего лямбда-выражения.

Для тех, кто интересуется, я написал заметки о том, как использовать библиотеку java.util.function: http://sysdotoutdotprint.com/index.php/2017/04/28/java-util-function-library/

Ответ 5

Вы также можете использовать библиотеку jOOL - https://github.com/jOOQ/jOOL

Он уже подготовил функциональные интерфейсы с различным количеством параметров. Например, вы можете использовать org.jooq.lambda.function.Function3 и т.д. От Function0 до Function16.

Ответ 6

Решением OOTB является импорт package kotlin.jvm.functions который определяет Function0, Function1, Function2... Function22,

например,

import kotlin.jvm.functions.*;

public void testFunction() {
    Function3<Integer, Integer, Integer, Integer> f3 = (x, y, z) -> x + y + z;
    System.out.println(f3.invoke(1, 2, 3));
    Function4<Integer, Integer, Integer, Integer, Integer> f4 = (a, b, c, d) -> a + b + c + d;
    System.out.println(f4.invoke(1, 2, 3, 4));
}

scala имеет схожие функции.

Ответ 7

Для использования лямбда: Существует три типа операции:
1. Принять параметр → Потребитель
2. Test parameter return boolean → Predicate
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);
}