Может ли 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, но не смог найти. Это возможно?
Ответы
Ответ 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);
}