۵ ویژگی جاوا ۸ که بدون آنها نمیتوانید زندگی کنید
اگر شما یک توسعهدهنده جاوا هستید حتما در مورد عبارت لامبدا در جاوا ۸ شنیدهاید. اما ممکن است ندانید که خیلی فراتر از یک عملگر فلش به جاوا ۸ اضافه شده است. در این مطلب به این موضوع میپردازیم که چقدر عبارت لامبدا و ویژگیهای دیگر جاوا ۸ زندگی شما را به عنوان توسعهدهنده آسان میکند.
عبارت لامبدا
تحولی که عبارات لامبدا ایجاد میکنند، تغییر در یک طرز فکر است. عبارت لامبدا ایده پاس دادن رفتار را به جای اشیا را تشویق میکند. برای مثال شما میتوانید یک تکه کد به یک متد بدهید تا اجرا کند.
userService = new Service<>("ws://localhost:8081/tweets/","/users/", 8083,message -> getTwitterHandleFrom(message));
کلاس Service شامل همه بخشهایی است که برای نمونه گیری از یک سوکت وب جدید نیاز است. این یک سرویس ساده است که به سرور متصل میشود که داده را دریافت کند و خود داده خود را روی (“/users/”, 8083) منتشر کند. آخرین پارامتر همان لامبداست که منطق را برای سرویس ما روشن میکند، پیامهای توئیتر را بگیرد، نام کاربری توئیتر را استخراج کرده و آن را منتشر کند.
قبل از لامبدا لازم بود که با استفاده از کپی/پیست کد منطق سرویسهای مختلف را جایگذاری میکردید یا اینکه یک کلاس سرویس abstract مینوشتید که برای هر سرویس override میشد. با استفاده از لامبدا، میتوانید روشنتر سطح زیرساختی سرویس را از کد منطق جدا کنید.
جویبار دادهها
API جویبار داده یک راه تمیز برای کوئری زدن به مجموعههایتان را فراهم میکند که میتواند مقدار کدی که مینویسید را کاهش دهد. برای مثال، یک پیامی را به یک لیستی از لغات آن پردازش کردید. فرض کنید یک Map دارید که یک کلمه را به یک حالت(خوشحال، ناراحت، عصبانی و …) نگاشت میکند شما میتوانید حالتی که پیام شما در بردارد را با چیزی مشابه زیر به دست آورید.
Set moods = wordsInTweet.stream() .map(String::toLowerCase) .map(lowerCaseWord -> WORD_TO_MOOD .get(lowerCaseWord)) .filter(mood -> mood != null) .collect(toSet());
اول کلمهها را به حروف کوچک تبدیل میکنیم، حالتی که مرتبط با کلمه است را استخراج میکنیم، هر nullای را فیلتر میکنیم و در نهایت آنها را در یک مجموعه قرار میدهیم. در اینجا یک عملیات پیچیده روی مجموعه را بدون هیچ حلقهای یا ذخیره کردن حالت میانی انجام میدهیم.
اگر قصد دارید کدتان را به جاوا ۸ تبدیل کنید، هرجایی که از حلقه for استفاده کردید را ببینید که آیا جویبار داده میتواند همان کار را در تعداد خط کد کمتری انجام دهد یا خیر.
توابع جدید روی مجموعهها
API جویبار داده یک راه برای اجرای خط لولهای عملگرها روی هرچیزی است که واسط Collection را پیادهسازی میکند. اما تنها همین نیست. مجموعهها متدهای کمکی جدیدی هم دارند که برای عملیاتهای معمولی به آنها اضافه شده اند.
شرایطی را در نظر بگیرید که میخواهید یک مقدار از Map را بخوانید یا یک مقدار جدید بسازید و در map یادداشت کنید. قبل از جاوا ۸ احتمالا این چنین این کار را میکردید:
private final Map<String, TwitterUser> allTwitterUsers = new HashMap<>(); public void onMessage(String twitterHandle) { TwitterUser twitterUser = allTwitterUsers.get(twitterHandle); if (twitterUser == null) { twitterUser = new TwitterUser(twitterHandle); allTwitterUsers.put(twitterHandle, twitterUser); } // then do something... }
اما الان یک تابع computeIfAbsent وجود دارد که بخش زیادی از کار را برایمان میکند.
private final Map<String, TwitterUser> allTwitterUsers = new HashMap<>;(); public void onMessage(String twitterHandle) { TwitterUser twitterUser = allTwitterUsers.computeIfAbsent(twitterHandle, (handle) -> new TwitterUser(handle)); // then do something... }
این تنها یک مثال از این توابع بود، در مستندات API موارد بیشتری خواهید یافت.
مقایسه کنندهها
مقایسه کنندهها اغلب مواردی هستند که از anonymous inner class ها استفاده میکردیم. با معرفی جویبار داده و متد sorted از آنها بیشتر از همیشه استفاده خواهیم کرد. تعریف توابع کمکی روی واسط کاربری Comparator آن را سادهتر میکند. سابقا برای مرتب کردن الفبایی چنین کدی مینوشتیم:
Comparator twitterUserComparator = new Comparator() { @Override public int compare(TwitterUser o1, TwitterUser o2) { return o1.getTwitterHandle().compareTo(o2.getTwitterHandle()); } };
حالا میتوانید از Comparator.comparing استفاده کنید
Comparator twitterUserComparator = Comparator.comparing(TwitterUser::getTwitterHandle);
اگر میخواهید به صورت نزولی مرتب کنید هم نیازی نیست که ترتیب مقایسه را عوض کنید، صرفا به این شکل میگویید:
Comparator twitterUserComparator = Comparator.comparing(TwitterUser::getTwitterHandle).reversed();
تاریخ و زمان
به جای استفاده از java.util.Date جایی که همه توابعی که مفید به نظر میرسند deprecated هستند، میتوانیم از یک API جدید برای تاریخ و زمان استفاده کنیم. حالا ایده تاریخ بدون زمان را داریم( Timezones، Periods و Duration) و یک API داریم که نامگذاری ها بسیار کارا و استادانه هستند. برای مثال به جای اینکه بدانیم شی Date زمان جاری را نشان میدهد میتوانیم به این شکل بگوییم:
LocalDateTime now = LocalDateTime.now();
میتوانیم عملیات منطقی روی زمان انجام دهیم:
LocalDateTime timeInTenMinutes = now.plusMinutes(10);
و مقادیر مشخصی را کوئری بزنیم:
int minute = now.getMinute(); DayOfWeek dayOfWeek = now.getDayOfWeek();
شما چه قابلیتی را مفیدتر از همه میدانید؟
منبع: