شروع Lambda جاوا
در سری مقالات آموزش جاوا, به مبحث Lambda در جاوا میپردازیم. در گذشته یک توضیح اجمالی پیرامون lambda ارائه شد. اما قصد داریم تا در سری مقالات lambda این مبحث را به تفصیل مورد بررسی قرار دهیم.
lambda expression در جاوا ۸ معرفی شد و به عنوان خاص ترین ویژگی جاوا ۸ شناخته شده است. دانستن ویژگی ها و مزایای lambda کمک میکند تا بتوان بهتر از آن استفاده کرد :
- functional programming : کد نویسی در جاوا بصورت شی گرا انجام میشود. اما lambda این ویژگی را فراهم کرده است که بتوان در جاوا به صورت functional programming نیز کد نویسی کرد
- کد نویسی مختصر و خوانایی بیشتر
- استفاده راحتر از API و library ها
- پشتیبانی از parallel processing
در ابتدا باید یک توضیح مختصر پیرامون Functional Programming ارائه دهیم و تفاوت آن با Object Oriented Programming بررسی کرد. سالیان بسیار زیادی است که در جاوا به صورت شی گرایی برنامه نویسی میشود و تمام نیاز های برنامه نویس از طریق شی گرایی برطرف گردیده است. شی گرایی امکانات زیادی در اختیار برنامه نویسان قرار داده است و در بعضی از موارد استفاده از آن بسیار حیاتی است. اما باید توجه داشت که functional programming امکانات بسیار جدیدی در اختیار برنامه نویس قرار نمیدهد. در حقیقت functional programming به برنامه نویس کمک میکند تا کد های خوانا تر و منسجم تری بنویسد. نباید چنین تفکری در ذهن خواننده بوجود آید که جاوا دیگر یک زبان شی گرا نیست. در حقیقت functional programming یک ابزار در کنار سایر ابزارهای برنامه نویسی جاوا است و باید در جای خود استفاده شود. در نگاه کلی برای پردازش های ثابت و مشخص بر روی موجودیت ها از شی گرایی استفاده میشود. موجودیت ها تغییر میکنند اما پردازش ها مشخص هستند. اگر نیاز باشد تا تغییر در پردازش خاصی اعمال شود, ممکن است تغییرات زیادی در ساختار پروژه ایجاد کند. در functional programming موجودیت ها ثابت هستند و پردازش ها متغیر هستند. موجودیت ها مشخص هستند و میتوان پردزاش های جدیدی بر روی آنها تعریف کرد. به این ترتیب اگر نیاز باشد موجودیت خاصی اضافه شود, ممکن است نیازمند پردازش های زیادی باشد.
به بیان ساده تر در شی گرایی همه فعالیت ها حول object ها است. تمام کد ها به کلاس ها و object های آن تعلق دارد. برای مثال وقتی که میخواهیم یک پیام را در خروجی به کاربر نمایش دهیم, نیاز است تا یک کلاس ایجاد کرده و متد را درون آن قرار دهیم. اما کاملا واضح است که در اینجا به کلاس احتیاجی نداریم. تنها به یک متد نیاز داریم تا این عمل را برای ما انجام دهد.
public class ZeroToHero { public void print() { System.out.println("Hello Zero to Hero"); } public static void main(String[] args) { ZeroToHero zeroToHero=new ZeroToHero(); zeroToHero.print(); } }
اما نمیخواهیم متد print تنها شامل یکسری دستور باشد. میخواهیم با استفاده از این متد یک رفتار مشخص را پیاده سازی کند. به این ترتیب یک interface ایجاد میکنیم و یک متد را به عنوان یک رفتار مشخص در آن تعریف میکنیم :
public interface ZeroToHeroInterface { public void message(); }
و در یک کلاس آنرا پیاده سازی میکنیم :
public class ZeroToHeroMessage implements ZeroToHeroInterface { @Override public void message() { System.out.println("Hello zero to hero"); } }
اکنون متد print را به این صورت تغییر میدهیم :
public class ZeroToHero { public void print(ZeroToHeroInterface messaging) { messaging.message(); } public static void main(String[] args) { ZeroToHero zeroToHero=new ZeroToHero(); ZeroToHeroMessage zeroToHeroMessage=new ZeroToHeroMessage(); zeroToHero.print(zeroToHeroMessage); } }
هدف ما در این مثال ارسال یک رفتار خاص بود اما همانطور که مشخص است یک موجودیت (Object) که شامل یک رفتار است را ارسال کرده ایم. بهتر بود که یک action به این متد ارسال و اجرا میشد.
public void print(action) { action(); }
lambda این امکان را میدهد تا چنین ماهیت هایی را که تنها تابع هستند ایجاد کنیم. با استفاده از lambda expression میتوان متد هایی ایجاد کرد که به کلاسی اختصاص ندارند و تنها توابعی هستند که به تنهایی رفتار میکنند و این توابع میتوانند به عنوان مقادیر (value) نیز در نظر گرفته شوند :
methodAsVariable = public void print() { System.out.println("Hello zero to hero"); }
و این متد که اکنون به یک متغیر تبدیل شده است را میتوان به عنوان رفتار خاصی ارسال کرد. اما چنین تعریفی باید دستخوش یکسری تغییرات شود.
در ابتدا کلمه کلیدی public باید حذف گردد. زیرا این کلمه در شی گرایی مفهوم دارد. public سطح دسترسی را مشخص میکند.ر اینجا ما میخواهیم این متغیر (و یا همان متد) را به متدی به عنوان رفتار ارسال کنیم. بدین ترتیب سطوح دسترسی در اینجا بی معنی است.
methodAsVariable = void print() { System.out.println("Hello zero to hero"); }
این متغیر دارای یک نام است. پس نام متد نیز میتواند حذف گردد.
methodAsVariable = void () { System.out.println("Hello zero to hero"); }
نوع مقداری که این متد برمیگرداند void است. در جاوا ۸, وقتی از lambda استفاده میشود, Compiler هوشمندانه نوع متغیری که توسط متد برگردانده میشود را شناسایی میکند. برای مثال متدی که جمع دو عدد را انجام میدهد, یک نوع داده عددی را بر میگرداند. در lambda نوع داده نتیجه را Compiler جاوا تشخیص میدهد.
methodAsVariable = () { System.out.println("Hello zero to hero"); }
با این روش ساده کردن میتوانید به خوبی شیوه نوشتن کد های lambda را درک کنید. و در نهایت کد به این شکل در میآید :
methodAsVariable = () -> System.out.println("Hello zero to hero");
برای مثال فرض کنید چنین متدی در جاوا داریم :
public int zeroToHeroAdding(int zero, int hero) { return zero + hero; }
مراحل بالا را روی آن پیاده میکنیم. ابتدا یک متغیر به آن اختصاص میدهیم.
add= public int zeroToHeroAdding(int zero, int hero) { return zero + hero; }
کلمه کلیدی public را حذف میکنیم. چون سطوح دسترسی در چنین روشی بی معنی است:
add= int zeroToHeroAdding(int zero, int hero) { return zero + hero; }
نام متد را حذف میکنیم زیرا متغیر یک نام دارد و دیگر به نام متد نیازی نداریم :
add= int (int zero, int hero) { return zero + hero; }
نوع مقداری که متد بر میگرداند حذف میشود زیرا کامپایلر نوع آنرا تشخیص میدهد :
add= int (int zero, int hero) { return zero + hero; }
و در نهایت کد به این صورت میشود :
add = (int zero, int hero) -> zero + hero;
توجه داشته باشید که کد های بالا به صورت شبه کد نوشته شده اند ودر این مقاله سعی بر این شد تا مفهوم lambda را مورد بررسی قرار دهیم. در مقاله بعدی به کد نویسی lambda میپردازیم.
سری مقالات آموزش lambda ادامه دارد.
با ما همراه باشید.
دیدگاهتان را بنویسید
برای نوشتن دیدگاه باید وارد بشوید.