لامبدا اکسپرشن امکان مهم و جدیدی است که در جاوا ۸ اضافه شده است که قبلا در C# مطرح شده بود. توسط لامبدا می توانیم توابعی را بصورت بی نام به همراه بدنه آن تعریف کنیم که مزایای گوناگونی از قبیل مختصر کردن کد، کم کردن تعداد فایل های .java پروژه را داراست. همچنین در هنگامی که می خواهیم از تابعی بر اساس شرایط استفاده کنیم و قابل استفاده است و یا مثلا در شرایط خاصی که نیاز به کلاس مشخصی داریم. فرض کنید در Runtime بر اساس رفتار کاربر قرار است توابع مختلفی ایجاد شود. همچنین می توان برای پاس دادن یک اینترفیس به یک تابع از لامبدا استفاده کرد که در آخرین مثال به آن اشاره می کنم.
لامبدا را به روش های گوناگونی می توان نوشت که در ادامه توضیح خواهم داد ولی روش کلی آن بصورت زیر است:
1 |
parameter -> expression body |
قسمت اول همانطور که مشخص است پارامترهای ورودی و بخش دوم بدنه می باشد.
برای استفاده از امکانات Lambda Expression در Android Studio باید فایل Gradle را بصورت زیر تغییر دهید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion '24.0.0' defaultConfig { applicationId "com.example.mtajik.accounttest" minSdkVersion 14 targetSdkVersion 23 versionCode 1 versionName "1.0" //for using java 8 and it's features like lambda expressions jackOptions { enabled true } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } sourceSets { main { aidl.srcDirs = ['src/main/aidl'] } } //for using java 8 and it's features like lambda expressions compileOptions { targetCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8 } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.4.0' } |
در کلاس زیر مثال چند توع لامبدا را خواهید دید. لامبدا اکسپرشن با نوع ورودی و بدون نوع ورودی، با بلاکی از کد و غیره.
1 2 3 4 5 |
۱٫ () -> 5 // takes no value and returns 5 ۲٫ x -> 2 * x // takes a number and returns the result of doubling it ۳٫ (x, y) -> x – y // takes two numbers and returns their difference ۴٫ (int x, int y) -> x + y // takes two integers and returns their sum ۵٫ (String s) -> System.out.print(s) // takes a string and prints it to console without returning anything |
به مثال های زیر را اجرا کرده و خروجی را ملاحظه نمایید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
public class Java8Tester { public static void main(String args[]){ Java8Tester tester = new Java8Tester(); //with type declaration MathOperation addition = (int a, int b) -> a + b; //with out type declaration MathOperation subtraction = (a, b) -> a - b; //with return statement along with curly braces MathOperation multiplication = (int a, int b) -> { return a * b; }; //without return statement and without curly braces MathOperation division = (int a, int b) -> a / b; System.out.println("10 + 5 = " + tester.operate(10, 5, addition)); System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction)); System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication)); System.out.println("10 / 5 = " + tester.operate(10, 5, division)); //with parenthesis GreetingService greetService1 = message -> System.out.println("Hello " + message); //without parenthesis GreetingService greetService2 = (message) -> { System.out.println("Hello my friend " + message); return; } ; //---without Lambda Expression GreetingService greetService3WithOutLambda = new GreetingService() { @Override public void sayMessage(String message) { System.out.println("Hello my friend " + message); } }; greetService1.sayMessage("mahdi"); greetService2.sayMessage("mahdi"); greetService3WithOutLambda.sayMessage("mahdi"); //sorting with Lambda Expression List<String> list = Arrays.asList("looooong", "short", "tiny" ); Collections.sort(list, (String s1, String s2) -> s1.length() + s2.length()); System.out.println(list); } interface MathOperation { int operation(int a, int b); } interface GreetingService { void sayMessage(String message); } private int operate(int a, int b, MathOperation mathOperation){ return mathOperation.operation(a, b); } } |
همانطور که ملاحظه می کنید اینترفیس هایی داریم که تعریف بدنه تابع های آن را با لامبدا اکسپرشن انجام دادیم. نمونه بدون لامبدااکسپرشن تابع greetiservice3WithoutLambda می باشد. همچنین با استفاده از لامبدا می توانید از روش مرتب سازی بالا نیز استفاده کنید. ( به قسمت sort توجه کنید) که برخلاف روش های گذشته بسیار ساده تر است. یعنی به جای نوشتن کلاس comparator به صورت مجزا، آن را بصورت لامبدا اکسپرشن در خود ورودی تولید کردیم.
یا اینکه بجای کد زیر :
1 2 3 4 5 6 |
LiveViewManager.registerView(QKPreference.HIDE_AVATAR_CONVERSATIONS, this, new LiveView() { @Override public void refresh(String key) { holder.mAvatarView.setVisibility(mContext.getBoolean(QKPreference.HIDE_AVATAR_CONVERSATIONS) ? View.GONE : View.VISIBLE); } }); |
بنویسم:
1 2 |
LiveViewManager.registerView(QKPreference.HIDE_AVATAR_CONVERSATIONS, this, key -> holder.mAvatarView.setVisibility(mContext.getBoolean(QKPreference.HIDE_AVATAR_CONVERSATIONS) ? View.GONE : View.VISIBLE)); |
همانطور که دیدید به جای new کردن Interface و سپس پاس دادن آن به تابع، بصورت مستقیم با لامبدا پاس دادیم.
منابع:
https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
http://www.tutorialspoint.com/java8/java8_lambda_expressions.htm
http://www.developer.com/java/start-using-java-lambda-expressions.html