может ли лямбда java иметь более 1 параметра?

<p>возможно ли в java лямбда-выражение принимать несколько разных типов?</p><p>i.e: отдельная переменная работает:</p><pre><code> function <integer, integer> adder = i -> i + 1; system.out.println (adder.apply (10)); </code></pre><p>varargs также работают:</p><pre><code> 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 }))); </code></pre><p>но я хочу что-то, что может принимать много разных типов аргументов, например:</p><pre><code> function <string, integer, double, person, string> mylambda = a , b, c, d-> { [do stuff] return "done stuff" }; </code></pre><p>основное использование - иметь небольшие встроенные функции внутри функций для удобства. </p><p>я посмотрел вокруг google и проверил функциональный пакет java, но не смог найти. это возможно?</p>

<p>это возможно, если вы определите такой функциональный интерфейс с несколькими параметрами типа. нет такого встроенного типа. (есть несколько ограниченных типов с несколькими параметрами.)</p><pre><code>@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'; } </code></pre><hr><p>также нет способа определить переменное число параметров типа, если это то, о чем вы спрашивали.</p><hr><p>некоторые языки, такие как scala, определяют ряд встроенных таких типов с параметрами типов 1, 2, 3, 4, 5, 6 и т.д.</p>

<p>для чего-то с 2 параметрами, вы можете использовать <code>bifunction</code>. если вам нужно больше, вы можете определить свой собственный интерфейс функции, например так:</p><pre><code>@functionalinterface public interface fourparameterfunction<t, u, v, w, r> { public r apply(t t, u u, v v, w w); } </code></pre><p>если имеется более одного параметра, вам нужно поместить скобки вокруг списка аргументов, например так:</p><pre><code>fourparameterfunction<string, integer, double, person, string> mylambda = (a, b, c, d) -> { // do something return "done something"; }; </code></pre>

<p>для этого случая вы можете использовать интерфейсы из библиотеки по умолчанию (java 1.8):</p><pre><code>java.util.function.biconsumer java.util.function.bifunction </code></pre><p>вот небольшой (не лучший) пример метода по умолчанию в интерфейсе:</p><pre><code>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 ""; }; }} </code></pre>

<p>другая альтернатива, не уверенная, применима ли она к вашей конкретной проблеме, но к некоторым она может быть применима, заключается в использовании <code>unaryoperator</code> в библиотеке java.util.function . , где она возвращает тот же тип, который вы указали, поэтому вы помещаете все свои переменные в один класс и это как параметр:</p><pre><code>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; } } </code></pre><p>таким образом, у вашего класса, в данном случае <code>person</code>, может быть множество переменных экземпляра, и вам не нужно будет изменять параметр вашего лямбда-выражения.</p><p>для тех, кто заинтересован, я написал заметки о том, как использовать библиотеку java.util.function: <a href="http://sysdotoutdotprint.com/index.php/2017/04/28/java-util-function-library/">http://sysdotoutdotprint.com/index.php/2017/04/28/java-util-function-library/</a> </p>

<p>вы также можете использовать библиотеку jool - <a href="https://github.com/jooq/jool">https://github.com/jooq/jool</a> </p><p>уже подготовлены функциональные интерфейсы с разным количеством параметров. например, вы можете использовать <code>org.jooq.lambda.function.function3</code> и т.д. от <code>function0</code> до <code>function16</code>.</p>

<p>решение ootb состоит в импорте <code>package kotlin.jvm.functions</code>, который определяет <code>function0</code>, <code>function1</code>, <code>function2</code> ... <code>function22</code>, </p><p>например.,</p><pre><code>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)); } </code></pre><p><code>scala</code> имеет аналогичные функции.</p>

<p>чтобы использовать лямбду: есть три типа операций:<br> 1. принять параметр -> потребитель<br> 2. тестовый параметр возвращает логическое значение -> предикат<br> 3. управление параметром и возвращаемым значением -> функция<br><br></p><p>функциональный интерфейс java до двух параметров:<br> <strong> интерфейс с одним параметром </strong><br> потребитель<br> predicate<br> функция<br> <br> <strong> двухпараметрический интерфейс </strong><br> biconsumer<br> bipredicate<br> bifunction<br></p><p><strong> для более чем двух </strong>, вы должны создать функциональный интерфейс следующим образом (тип потребителя):</p><pre><code>@functionalinterface public interface fiveparameterconsumer<t, u, v, w, x> { public void accept(t t, u u, v v, w w, x x); } </code></pre>