لاندا Lambda
کاربرد:
lambda برای پیاده سازی interfaceهایی استفاده میشود که یک متد دارند.
با استفاده از lambda میتوان به راحتی از Collectionها استفاده کرد(عملیاتهایی همچون iterate، فیلتر و سرچ
ساختار:
(argument-list) -> {body}
در عبارت لامبدا ، سمت چپ عبارت پارامترهای موردنیاز عبارت را مشخص می کند ، در حالی که سمت راست بدنه ی لامبدا است
نمونه:
() -> System.out.println(“Lambdas are great”);
(n) -> (n%2)==0
() -> { double pi = 3.1415; return pi; }
نمونه جایگزینی تعریف یک کلاس لوکال با یک لاندا:
interface Drawable { public void draw(); } public class LambdaExpressionExample { public static void main(String[]args) { // Drawable d = new Drawable() { // public void draw() { // System.out.println("Drawing "); // } // }; Drawable d2 = ()->System.out.println("Drawing "); d.draw(); } }
(بخشهایی که کامنت شدهاند جایگزین شدهاند.)
public interface MyInterface { double getPiValue(); } public class LambdaMain { public static void main(String[]args) { MyInterface myInterface; myInterface = ()->3.1415; System.out.println(“Value of Pi = ” + myInterface.getPiValue()); } }
کاربرد لاندا در اینترفیسی که با تایپ عمومی T تعریف شده باشد (رابط کاربری عمومی) :
interface GenericInterface < T > { T func(T t); } //_________________________ public class GenericLambda { public static void main(String[]args) { // GenericInterface < String > reverse = (str)->{ String result = “”; for (int i = str.length() - 1; i >= 0; i–) result += str.charAt(i); return result; }; // GenericInterface < Integer > factorial = (n)->{ int result = 1; for (int i = 1; i <= n; i++) result = i * result; return result; }; // System.out.println(“Lambda reversed = ” + reverse.func(“Lambda”)); System.out.println(“factorial of 5 = ” + factorial.func(5)); } } //_________________________ //outputs: // Lambda reversed = adbmaL // factorial of 5 = 120
ایجاد حلقه بر روی یک فهرست یا مجموعه
کلاسهای کلکسیون مانند List، Set، Queue و امثال آن اینترفیس Iterable را پیادهسازی کردهاند که ایجاد حلقه بر روی عناصر را آسانتر ساخته است. (سه عبارت زیر با هم برابر هستند.)
for (String name: names) { System.out.println(name); } names.forEach(name -> System.out.println(name)); names.forEach(System.out::println);
دو عبارت زیر با هم برابر هستند:
for (Map.Entry<String,Integer> e : map.entrySet()) { System.out.println(e.getKey() + " => " + e.getValue()); } map.forEach((k, v) -> System.out.println(k + " => " + v));
نمونهای دیگر از بهکارگیری لاندا. با استریم:
List<String> myPlaces = getPlaces(); myPlaces.stream() .filter((p) -> p.startsWith(“aleph”)) .map((p) -> p.toUpperCase()) .sorted();
اینترفیسهای کاربردی
عبارات لاندا فقط می تونن جای functional interface بشینن. اینا در واقع اینترفیس هایی هستن که فقط یدونه abstract method دارن. بنابراین نمیشه برای interfaceهای با بیشتر از یه abstract متد استفادشون کرد و بی معنی هم هست این کار چون ابهام درست میکنه.
اگر چنین اینترفیسی داشته باشین (مثل MouseListener) باید ابتدا یه اینترفیس فرزند ازش درست کنید و همه متدهایی که نمیخواین رو جز اون یکی که میخواین default کنید!
بعد ازش استفاده کنید! به نقل از cups_of_java
Thread
به جای این عبارت:
class MyTask implements Runnable { public void run() { System.out.println("Running in a separate thread now."); } } MyTask task = new MyTask();
میتوان نوشت:
Runnable task = ()->System.out.println("Running in a separate thread now.");
ترجمه عامیانه عبارت بالا: یک آبجکت ایجاد کن به نام تسک که از اینترفیس رانابل ارثبری داشته باشد که داخل آن اینترفیس تنها یک متد هست و داخل متد را هم اینگونه پر کن.