عبارت‌های لامبدا (lambda) در جاوا ۸ — مرور سریع

۵۷۳ بازدید
آخرین به‌روزرسانی: ۰۶ شهریور ۱۴۰۲
زمان مطالعه: ۴ دقیقه
عبارت‌های لامبدا (lambda) در جاوا ۸ — مرور سریع

اگر برنامه‌نویس جاوا هستید یا علاقه‌مندید که اطلاعات بیشتری در مورد عبارت‌های لامبدا در جاوا 8 بدانید، در این نوشته با ما همراه باشید تا نگاهی به ساختار لامبدا و استفاده‌های آن داشته باشیم.

عبارت لامبدا در جاوا، روش فشرده‌ای برای بیان متد یک کلاس در یک عبارت منفرد است. عبارت لامبدا یک فهرست پارامتر و یک بدنه دارد. بدنه این عبارت می‌تواند یک عبارت منفرد یا یک بلوک کد باشد. این عبارت معمولاً هنگامی استفاده می‌شود که پیاده‌سازی یک اینترفیس ضروری باشد. این نیاز به طور معمول زمانی رخ می‌دهد که یک اینترفیس به عنوان یک آرگومان برای فراخوانی یک متد لازم باشد.

برخی عبارت‌های ساده لامبدا

در ادامه برخی نمونه‌های ساده از عبارت‌های لامبدا را ارائه کرده‌ایم.

عبارت لامبدای زیر دو عدد x و y را گرفته و مجموع آن‌ها را محاسبه می‌کند:

1(int x,int y) -> x + y;

نوع پارامتر برای نمایش خلاصه‌تر حذف شده است:

1(x, y) -> x + y;

می‌توان توابعی را تعریف کرد که پارامتری نمی‌پذیرند:

1() -> 404;

تابع زیر نیز معتبر است و هیچ پارامتری نپذیرفته و هیچ مقداری را نیز بازنمی‌گرداند:

1() -> {}

اگر یک پارامتر وجود داشته باشد نیازی نیست، داخل پرانتز نوشته شود:

1x -> x + 1

بلوک‌های کد پیچیده‌تر نیز وجود دارند. مثلاً عبارت لامبدای زیر یک پارامتر تک‌خطی می‌گیرد و برخی محاسبات روی آن انجام می‌دهد. توجه کنید که نوع پارامتر از روی فاکتورهای جانبی مشخص شده است:

1line -> {
2String[] x = pattern.split(line);
3return new Player(Integer.parseInt(x[0]),
4x[1],
5x[2],
6x[3],
7Integer.parseInt(x[4]));
8}

کدنویسی تمیز و فشرده

با استفاده از عبارت‌های لامبدا می‌توان کد مرتب و فشرده‌ای نوشت. بدین منظور کلاس‌های جاوا 8 استفاده گسترده‌ای از لامبدا داشته‌اند.

ایجاد حلقه بر روی یک فهرست یا مجموعه

کلاس‌های کلکسیون مانند List، Set، Queue و امثال آن اینترفیس Iterable را پیاده‌سازی کرده‌اند که ایجاد حلقه بر روی عناصر را آسان‌تر ساخته است.

یک فهرست نام‌ها اعلان می‌کنیم:

1List<String> names = Arrays.asList("Joe", "Jack", "James", "Albert");

بدون لامبدا روی عناصر آن حلقه‌ای تعریف می‌کنیم:

1for (String name: names) {
2System.out.println(name);
3}

با استفاده از لامبدا، کد حلقه فوق را می‌توان چنین نوشت:

1names.forEach(name -> System.out.println(name));

ارجاع‌های متد در جاوا 8 طوری است که کد فوق را می‌توان از این هم فشرده‌تر نوشت:

1names.forEach(System.out::println);

ایجاد حلقه بر روی map

یک map درواقع نگاشتی از یک مجموعه کلید به مجموعه مقادیر است. برای ایجاد حلقه بر روی یک map باید بر روی هر یک از مجموعه‌های (کلید، مقدار) حلقه‌هایی داشت. در مثال‌های زیر نحوه استفاده از حلقه را در این مورد می‌بینیم.

ابتدا یک map تعریف می‌کنیم:

1Map<String,Integer> map = new HashMap<>();
2map.put("Atlanta, Georgia", 110);
3map.put("Austin, Texas", 115);
4map.put("Baltimore, Maryland", 105);
5map.put("Birmingham, Alabama", 99);
6map.put("Boston, Massachusetts", 98);

می‌توان به روش سنتی بر روی این map یک حلقه تعریف کرد:

1for (Map.Entry<String,Integer> e : map.entrySet()) {
2System.out.println(e.getKey() + " => " + e.getValue());
3}

در ادامه کد فوق را به روش سریع و فشرده با استفاده از لامبدا نوشته‌ایم:

1map.forEach((k, v) -> System.out.println(k + " => " + v));

اینترفیس‌های کاربردی

مقدار بازگشتی یک عبارت لامبدا چیست؟ به بیان دیگر در گزاره زیر نوع X کدام است؟

1X x = a -> a + 1;

مقدار بازگشتی یک عبارت لامبدا، اینترفیس کاربردی است. یعنی اینترفیسی که یک متد انتزاعی (abstract) منفرد دارد. می‌توان یک عبارت لامبدا را با استفاده از متد انتزاعی مطابق خود به یک اینترفیس انتساب داد. در ادامه نمونه‌هایی ارائه کرده‌ایم.

ایجاد یک وظیفه چندنخی (Multi-Thread)

برای ایجاد وظیفه‌ای که دریک نخ جداگانه اجرا می‌شود، باید این وظیفه را به عنوان یک اینترفیس اجرایی (Runnable) تعریف کرده و با استفاده متد ()run اجرا کنید. در اینجا Runnable یک اینترفیس کاربردی است.

1class MyTask implements Runnable {
2...
3public void run() {
4// implement your task here
5System.out.println("Running in a separate thread now.");
6}
7...
8}

سپس می‌توان یک وهله از کلاس MyTask تعریف کرده و از آن برای شروع یک نخ اجرایی جدید استفاده نمود.

1MyTask task = new MyTask();
2
3Thread thread = new Thread(task);
4
5thread.start()

فرایند ایجاد یک Runnable با استفاده لامبدا بسیار آسان‌تر می‌شود. تعریف وظیفه فوق را می‌توان به صورت زیر بازنویسی نمود:

1Runnable task = () -> System.out.println("Running in a separate thread now.");

و یا حتی می‌توان فشرده‌تر نوشت:

1Thread thread = new Thread(() -> System.out.println("Running in a separate thread now."));
2thread.start();

مقایسه با استفاده از Comparator

یک Comparator در واقع اینترفیس کاربردی برای مقایسه اشیایی با نوع مفروض است. این اینترفیس یک متد مجرد منفرد به نام ()compare تعریف می‌کند که می‌توان با استفاده از لامبدا را نیز آن را تعریف نمود.

عبارت لامبدای زیر یک Comparator ایجاد می‌کند که برای مقایسه رشته‌هایی به صوت حساس به حروف کوچک و بزرگ استفاده می‌شود:

1Comparator<String> cmp = (x, y) -> x.compareToIgnoreCase(y);

زمانی که یک وهله از اینترفیس کاربردی Comparator ایجاد شد، می‌توان در صورت نیاز آن را مورد استفاده مجدد قرار داد.

در ادامه یک فهرست از رشته‌ها را به صورت صعودی مرتب می‌کنیم.

1List<String> names = Arrays.asList("Joe", "Jack", "James", "Albert");
2Collections.sort(names, cmp);
3names.forEach(System.out::println);
4// prints
5Albert
6Jack
7James
8Joe

فهرست فوق مرتب‌سازی شده‌ است. اینک می‌توانیم با استفاده از متد binarySearch() آن را مورد جستجو قرار دهیم:

1System.out.println("search(Joe):" + Collections.binarySearch(names, "Joe", cmp));
2# prints
3search(Joe):3

محاسبه مینیمم و ماکزیمم یک فهرست نیز با استفاده از لامبدا کار آسانی است.

در ادامه برخی داده‌ها را تعریف کرده‌ایم:

1List<Integer> temps = Arrays.asList(110, 115, 105, 99, 98, 54, 109, 84, 81, 66, 72, 135, 115, 75, 82, 90, 88);

از عبارت لامبدا برای تعریف comparator استفاده می‌کنیم:

1Comparator<Integer> cmpTemp = (x, y) -> Integer.compare(x, y);

و ماکزیمم و مینیمم را چاپ می‌کنیم:

1System.out.println("------ Max/Min ------");
2System.out.println(Collections.max(temps, cmpTemp) + "/" + Collections.min(temps, cmpTemp));

استفاده از لامبدا در برنامه‌نویسی رابط کاربری گرافیکی (GUI)

عبارت‌های لامبدا در برنامه‌نویسی GUI نیز جهت پیاده‌سازی handler های رویداد بسیار مفید هستند. در ادامه نمونه‌ی استفاده از یک handler برای کلیک دکمه را می‌بینید:

1JButton button = new JButton("Click Me");
2button.addActionListener(e -> System.out.println("Button clicked!"));

در این نوشته تلاش کردیم مروری سریع بر لامبدا و استفاده‌های آن در جاوا 8 داشته باشیم. اگر فکر می‌کنید استفاده از لامبدا باعث راحت‌تر شدن کارها شده است، لطفاً نظرات خود را در بخش زیر با ما در میان بگذارید.

اگر به این مطلب علاقه‌مند بوده‌اید، آموزش‌های زیر نیز احتمالاً مورد توجه شما واقع خواهند شد:

==

بر اساس رای ۱۰ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
makeuseof
۱ دیدگاه برای «عبارت‌های لامبدا (lambda) در جاوا ۸ — مرور سریع»

بسیار عالی متشکر

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *