Вызов функции Java 8
Я использую Java 8 в последние пару месяцев и пытаюсь разобраться с лямбдами. У меня есть немного понимания о концерте. Но борется с выполнением пользовательского функционального интерфейса как лямбда-вызов.
Если я создаю реализацию Java Bifuctional интерфейса
BiFunction<t1,t2,R> trade = (t1, t2) -> {
// calling another method for merger
return t1,t2;
};
Могу ли я назвать это лямбда, как показано ниже?
(a, b)-> trade:
Или я должен создать метод execute?
private int execute(BiFunction<t1,t2,R> trade, int a, int b){
return trade.apply(a, b)
}
Вот пример кода, который вызывает лямбду:
BiFunction<t1,t2,R> trade = (t1, t2) -> {
// calling another method for merger return t1+t2;
};
public static void main(String[] args) {
execute(trade , 1, 2);
}
private int execute(BiFunction<t1,t2,R> trade, int a, int b) {
return trade.apply(a, b);
}
Мне любопытно, почему компилятор не может этого понять
public static void main(String[] args) { int i= (1,2) -> trade; }
2 ответа
Если вы долгое время работали с Java-кодером, новый лямбда-материал может сбить с толку - это было (есть?) Для меня. Лямбды - это контекстная конструкция, которую компилятор интерпретирует на основе контекста, в котором он используется, как и многие другие языки сценариев. В большинстве случаев вам никогда не нужно создавать свои собственные подтипы, потому что компилятор делает это за вас в зависимости от того, где вы их используете. Объективно, мы думаем: "Да, я знаю. Дух". Но трудно заставить свой мозг изменить образ мыслей. Это одно из больших препятствий, которое, я думаю, нужно преодолеть многим разработчикам.
Я вижу, как мы хотим думать: "Ну и дела, я хочу свой собственный BiConsumer
что объединяет два Strings
и добавляет их в List
Msgstr "Итак, вы генерируете свой файл класса в вашей любимой IDE и получаете
public static class StringConcat implements BiConsumer<String,String>{
private List<String> values = new ArrayList<>();
@Override
public void accept(String s, String s2) {
values.add(s,s2);
}
}
И когда вы пытаетесь найти хорошее применение, вы не можете найти его. Это потому, что нет необходимости создавать его.
Мне было трудно найти ситуацию, когда мне нужно создать свой собственный класс, который реализует любой из java.util.function
вещи. Не говоря о том, что случаев нет, просто я не нашел слишком много.
Это сводится к распознаванию, когда у вас есть что-то, что принимает тип, который имеет единственный абстрактный метод, например Comparable.compare(T t1, T t2)
или же Runnable.run()
, В этих случаях вы просто встроите лямбда-конструкцию.
Так что используя функциональность моего StringConcat
, учитывая Map<String,String> map
// I just passed it a new BiConsumer!
map.forEach((k,v)-> list.add(k+v));
РЕДАКТИРОВАТЬ: После ваших комментариев и перечитывания вашего вопроса, я думаю, что у вас все еще есть немного психического блока. Похоже, что вы хотите объявить лямбду, создать его экземпляр и вызвать его в три этапа. Такого рода побеждает цель. Когда вы используете лямбду, вы делаете первые два шага, когда вы создаете лямбду, встроенную с чем-то, что ее принимает.
// declare AND instantiate
stringList.stream().map(string -> Integer.parseInt(string))...
Это говорит "для каждой строки в списке, примените эту функцию, Integer.parseInt(string)
"Обратите внимание, что вы никогда не звоните apply()
, Это сделано в рамках map
метод. Это избавляет от необходимости делать то, что вы делаете, создавая экземпляр и пытаясь вызвать его отдельно.
Лямбды не волшебная пуля. В большинстве случаев вам все еще нужны отдельные методы с разными операторами. Возможно, нужная вам функциональность не очень хорошо работает с лямбдами.
Вы используете лямбда, как это
public static void main(String[] args) {
BiFunction<Integer, Integer, Integer> add = (x, y) -> {
return x + y;
};
System.out.println(add.apply(1, 2));
}