Di Java 8, metode yang dapat dibuat sebagai ekspresi Lambda dan dapat dilalui oleh referensi (dengan sedikit bekerja di bawah kap mesin). Ada banyak contoh online dengan lambdas yang diciptakan dan digunakan dengan metode, tetapi tidak ada contoh bagaimana membuat sebuah metode mengambil lambda sebagai parameter. Apa adalah sintaks untuk itu?
MyClass.method((a, b) -> a+b);
class MyClass{
//How do I define this method?
static int method(Lambda l){
return l(5, 10);
}
}
Lambdas adalah murni panggilan-situs membangun: penerima lambda tidak perlu tahu bahwa Lambda yang terlibat, melainkan menerima sebuah Antarmuka dengan metode yang sesuai.
Dengan kata lain, anda tentukan atau menggunakan antarmuka fungsional (yaitu antarmuka dengan metode tunggal) yang menerima dan mengembalikan apa yang anda inginkan.
Selama ini Jawa 8 datang dengan satu set yang sering digunakan antarmuka jenis di jawa.util.fungsi
(terima kasih kepada Maurice Naftalin untuk petunjuk tentang JavaDoc).
Untuk penggunaan tertentu ini kasus ada's jawa.util.fungsi.IntBinaryOperator
dengan single int applyAsInt(int kiri, int kanan)
metode, sehingga anda dapat menulis metode
seperti ini:
static int method(IntBinaryOperator op){
return op.applyAsInt(5, 10);
}
Tetapi anda dapat juga menentukan antarmuka anda sendiri dan menggunakannya seperti ini:
public interface TwoArgIntOperator {
public int op(int a, int b);
}
//elsewhere:
static int method(TwoArgIntOperator operator) {
return operator.op(5, 10);
}
Menggunakan antarmuka anda sendiri memiliki keuntungan bahwa anda dapat memiliki nama yang lebih jelas menunjukkan maksud.
Untuk menggunakan Lambda expression yang anda butuhkan untuk membuat anda sendiri fungsional antarmuka atau menggunakan Java fungsional antarmuka untuk operasi yang memerlukan dua buah integer dan mengembalikan nilai. IntBinaryOperator
Menggunakan user didefinisikan fungsional antarmuka
interface TwoArgInterface {
public int operation(int a, int b);
}
public class MyClass {
public static void main(String javalatte[]) {
// this is lambda expression
TwoArgInterface plusOperation = (a, b) -> a + b;
System.out.println("Sum of 10,34 : " + plusOperation.operation(10, 34));
}
}
Menggunakan Java fungsional antarmuka
import java.util.function.IntBinaryOperator;
public class MyClass1 {
static void main(String javalatte[]) {
// this is lambda expression
IntBinaryOperator plusOperation = (a, b) -> a + b;
System.out.println("Sum of 10,34 : " + plusOperation.applyAsInt(10, 34));
}
}
Contoh lain yang saya buat ini di sini
Untuk fungsi yang tidak memiliki lebih dari 2 parameter, anda dapat melewati mereka tanpa mendefinisikan antarmuka anda sendiri. Misalnya,
class Klass {
static List<String> foo(Integer a, String b) { ... }
}
class MyClass{
static List<String> method(BiFunction<Integer, String, List<String>> fn){
return fn.apply(5, "FooBar");
}
}
List<String> lStr = MyClass.method((a, b) -> Klass.foo((Integer) a, (String) b));
Di BiFunction<Integer, String, Daftar<String>>
, Integer
dan String
adalah parameter, dan Daftar<String>
adalah jenis kembali.
Untuk fungsi dengan hanya satu parameter, anda dapat menggunakan Fungsi<T, R>
, dimana T
adalah jenis parameter, dan R
adalah nilai kembali jenis. Merujuk ke halaman untuk semua interface yang sudah disediakan oleh Java.
Ada's Web publik yang dapat diakses versi Lambda-enabled Jawa 8 JavaDocs, terkait dari http://lambdafaq.org/lambda-resources. (Ini jelas harus komentar di Joachim Sauer's jawaban, tapi aku bisa't masuk ke saya SEHINGGA akun dengan reputasi poin yang perlu saya tambahkan komentar.) Yang lambdafaq situs (saya menjaga itu) jawaban ini dan banyak lainnya Jawa-lambda pertanyaan.
NB jawaban Ini ditulis sebelum Jawa 8 GA dokumentasi menjadi tersedia secara publik. I've tersisa di tempat, meskipun, karena Lambda FAQ mungkin masih bisa berguna untuk orang-orang belajar tentang fitur-fitur yang diperkenalkan di Jawa 8.
Bagi siapa saja yang googling ini, metode yang baik akan menggunakan jawa.util.fungsi.BiConsumer
.
ex:
Import java.util.function.Consumer
public Class Main {
public static void runLambda(BiConsumer<Integer, Integer> lambda) {
lambda.accept(102, 54)
}
public static void main(String[] args) {
runLambda((int1, int2) -> System.out.println(int1 + " + " + int2 + " = " + (int1 + int2)));
}
Yang outprint akan sama: 166
Untuk saya, solusi yang paling masuk akal adalah untuk mendefinisikan Balik
interface :
interface Callback {
void call();
}
dan kemudian menggunakannya sebagai parameter dalam fungsi yang ingin anda hubungi :
void somewhereInYourCode() {
method(() -> {
// You've passed a lambda!
// method() is done, do whatever you want here.
});
}
void method(Callback callback) {
// Do what you have to do
// ...
// Don't forget to notify the caller once you're done
callback.call();
}
Lambda tidak khusus antarmuka, kelas, atau apa pun yang anda bisa menyatakan dengan diri sendiri. Lambda
adalah nama yang diberikan untuk () -> {}
sintaks khusus, yang memungkinkan pembacaan yang lebih baik ketika melewati satu metode interface sebagai parameter. Hal ini dirancang untuk menggantikan ini :
method(new Callback() {
@Override
public void call() {
// Classic interface implementation, lot of useless boilerplate code.
// method() is done, do whatever you want here.
}
});
Jadi dalam contoh di atas, Balik
adalah tidak lambda, it's just a regular antarmuka ; lambda
adalah nama shortcut sintaks yang dapat anda gunakan untuk menerapkannya.
Ekspresi Lambda dapat dilewatkan sebagai argumen.Untuk lulus ekspresi lambda sebagai argumen jenis parameter (yang menerima ekspresi lambda sebagai argumen) harus fungsional jenis antarmuka.
Jika ada antarmuka fungsional -
interface IMyFunc {
boolean test(int num);
}
Dan ada metode filter yang menambah int dalam daftar hanya jika lebih besar dari 5. Perhatikan di sini bahwa metode filter memiliki funtional antarmuka IMyFunc sebagai salah satu parameter. Dalam hal ini ekspresi lambda dapat dilewatkan sebagai argumen untuk parameter metode.
public class LambdaDemo {
public static List<Integer> filter(IMyFunc testNum, List<Integer> listItems) {
List<Integer> result = new ArrayList<Integer>();
for(Integer item: listItems) {
if(testNum.test(item)) {
result.add(item);
}
}
return result;
}
public static void main(String[] args) {
List<Integer> myList = new ArrayList<Integer>();
myList.add(1);
myList.add(4);
myList.add(6);
myList.add(7);
// calling filter method with a lambda expression
// as one of the param
Collection<Integer> values = filter(n -> n > 5, myList);
System.out.println("Filtered values " + values);
}
}
Anda dapat menggunakan fungsional antarmuka seperti yang disebutkan di atas. di bawah ini adalah beberapa contoh
Function<Integer, Integer> f1 = num->(num*2+1);
System.out.println(f1.apply(10));
Predicate<Integer> f2= num->(num > 10);
System.out.println(f2.test(10));
System.out.println(f2.test(11));
Supplier<Integer> f3= ()-> 100;
System.out.println(f3.get());
Semoga membantu
Nah, yang's mudah. Tujuan dari ekspresi lambda adalah untuk mengimplementasikan Antarmuka Fungsional. Ini adalah antarmuka dengan hanya satu metode. Berikut ini adalah awesone artikel tentang yang telah ditetapkan dan warisan fungsional antarmuka.
Lagi pula, jika anda ingin menerapkan sendiri fungsional antarmuka, membuat itu. Hanya untuk contoh sederhana:
public interface MyFunctionalInterface {
String makeIt(String s);
}
Jadi let's membuat sebuah kelas, dimana kita akan membuat sebuah metode, yang menerima jenis MyFunctionalInterface :
public class Main {
static void printIt(String s, MyFunctionalInterface f) {
System.out.println(f.makeIt(s));
}
public static void main(String[] args) {
}
}
Hal terakhir yang harus anda lakukan adalah untuk lulus pelaksanaan MyFunctionalInterface untuk metode kami've didefinisikan:
public class Main {
static void printIt(String s, MyFunctionalInterface f) {
System.out.println(f.makeIt(s));
}
public static void main(String[] args) {
printIt("Java", s -> s + " is Awesome");
}
}
Yang's itu!
Lambda adalah bukan obyek tetapi Fungsional Antarmuka. Satu dapat menentukan sebanyak Fungsional Antarmuka karena mereka dapat menggunakan @FuntionalInterface sebagai anotasi
@FuntionalInterface
public interface SumLambdaExpression {
public int do(int a, int b);
}
public class MyClass {
public static void main(String [] args) {
SumLambdaExpression s = (a,b)->a+b;
lambdaArgFunction(s);
}
public static void lambdaArgFunction(SumLambdaExpression s) {
System.out.println("Output : "+s.do(2,5));
}
}
Output akan menjadi sebagai berikut
Output : 7
Konsep Dasar dari Ekspresi Lambda adalah untuk menentukan logika anda sendiri tapi sudah didefinisikan Argumen. Jadi pada kode diatas anda dapat mengubah definisi apakah fungsi dari samping apapun definisi lain, tapi argumen anda yang terbatas 2.
Pada dasarnya untuk lulus lamda ekspresi sebagai parameter, kita perlu jenis di mana kita bisa menahannya. Hanya sebagai integer nilai yang kita pegang dalam primitif int atau bilangan Bulat kelas. Jawa doesn't memiliki jenis yang terpisah untuk lamda ekspresi melainkan menggunakan antarmuka seperti jenis untuk menahan argumen. Tetapi antarmuka yang harus fungsional antarmuka.
Lakukan hal berikut ..
Anda telah menyatakan method(lambda l)
Semua yang anda ingin lakukan adalah membuat sebuah Interface dengan nama lambda
dan menyatakan satu metode abstrak
public int add(int a,int b);
nama metode tidak peduli di sini..
Jadi ketika anda menelepon MyClass.metode( (a,b)->a+b)
Implementasi ini (a,b)->a+b
akan disuntikkan ke antarmuka anda menambahkan metode .Jadi, setiap kali anda menelepon aku.tambahkan
itu akan mengambil implementasi ini dan melakukan penambahan a
dan b
dan kembali l.tambahkan(2,3)
akan kembali 5
.
Ada fleksibilitas dalam menggunakan lambda sebagai parameter. Hal ini memungkinkan pemrograman fungsional di jawa. Sintaks dasar adalah
param -> method_body
Berikut adalah sebuah way, anda dapat menentukan metode pengambilan fungsional antarmuka (lambda digunakan) sebagai parameter.
a. jika anda ingin mendefinisikan sebuah metode yang dideklarasikan di dalam sebuah antarmuka fungsional,
dikatakan, fungsionalantarmuka** diberikan sebagai argumen/parameter untuk metode yang disebut dari main()
@FunctionalInterface
interface FInterface{
int callMeLambda(String temp);
}
class ConcreteClass{
void funcUsesAnonymousOrLambda(FInterface fi){
System.out.println("===Executing method arg instantiated with Lambda==="));
}
public static void main(){
// calls a method having FInterface as an argument.
funcUsesAnonymousOrLambda(new FInterface() {
int callMeLambda(String temp){ //define callMeLambda(){} here..
return 0;
}
}
}
/***********Can be replaced by Lambda below*********/
funcUsesAnonymousOrLambda( (x) -> {
return 0; //(1)
}
}
FInterface fi = (x) -> { return 0; };
funcUsesAnonymousOrLambda(fi);
di Sini di atas dapat dilihat, bagaimana ekspresi lambda dapat diganti dengan sebuah antarmuka.
Di atas menjelaskan penggunaan tertentu dari ekspresi lambda, ada lebih. ref https://stackoverflow.com/questions/23451579/java-8-lambda-within-a-lambda-cant-modify-variable-from-outer-lambda