کد نویسی سریع و ساده با Lambda در جاوا
جاوا ۸ تکنولوژی جدیدی را ارائه کرده که سرعت برنامه نویس را بسیار بالا میبرد و کد نویسی زمانگیر متند ها و مخصوصا پیاده سازی یکسری متد های اینترفیس هارا بسیار خلاصه تر و سریع تر برای برنامه نویس ممکن میکند . همیشه حجم زیادی از کد ها مربوط به پیاده سازی متد های اینترفیس ها میشد ولی چه بهتر است که بتوان یک مقایسه بین دو آیتم که در ۱۱ خط انجام میشد را در یک خط انجام دهیم !!!!
با استفاده از lambda میتوان سرعت کد نویسی را بهبود بخشید و بسیار ساده تر با متد های اینترفیس ها کار کرد . پس چه بهتر است که برای استاندارد کردن کد ها و پرهیز از نوشتن بدنه اینترفیس ها که از این به بعد دیگر کاری بی فایده خواهد بود , از lambda استفاده کنیم.
خب کار را از کلاس Thread شروع میکنیم :
Thread nonstandard =new Thread(new Runnable() { @Override public void run() { System.out.println("i'm zero "); } }); nonstandard.start();
اجرای این کد خود گواه است :
i'm zero
حال ببینیم این کد با lambda چطور نوشته میشود . در lambda به این صورت کد نویسی میشود :
method((param1,param2,...) -> body code of interface method)
برای مثال کدی که بالا نوشتیم به این صورت میشود :
Thread standard = new Thread(() -> System.out.println("i'm hero")); standard.start();
در کد بالا
(() ->
به معنای این میباشد که این متد ورودی ندارد همانطور که در متد اصلی اینطور است :
public void run()
و بعد از ان
System.out.println("i'm hero"));
که به عنوان بدنه متد میباشد :
@Override public void run() { System.out.println("i'm zero "); } });
به چند مثال دیگر میپردازیم تا با کاربرد lambda بیشتر آشنا شویم :
ابتدا یک کلاس مدل میسازیم با عنوان user :
public class User { private String name; private int id; private float rank; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public float getRank() { return rank; } public void setRank(float rank) { this.rank = rank; } public User(String name, int id, float rank) { this.name = name; this.id = id; this.rank = rank; } }
List<User> users = new ArrayList<>(); users.add(new User("hero user 1", 1, 1.5f)); users.add(new User("hero user 2", 2, 2f)); users.add(new User("hero user 3", 3, 2f)); users.add(new User("hero user 4", 4, 0.5f)); users.add(new User("hero user 5", 5, 3f));
حالا میخواهیم یک لیست از این مدل را بر اساس rank آنها مرتب کنیم . بر اساس کدی که تا به حال مینوشتیم باید به این صورت بنویسیم :
Comparator<User> userComparator =new Comparator<User>() { @Override public int compare(User u1, User u2) { return Float.compare(u1.getRank(), u2.getRank()); } }; users.sort(userComparator.reversed()); for (User user : users) { System.out.println(user.getName() + " : " + user.getRank()); } }
حالا این کد با lambda مینویسیم :
users.sort((u1, u2) -> (Float.compare(u1.getRank(), u2.getRank()))); Collections.reverse(users); users.forEach(u -> System.out.println(u.getName() + " : " + u.getRank()));
همانطور که میبینیم کد بسیار خلاصه تر شده است . همین کد نیز میتواند به صورت بسیار ساده تر نیز نوشته شود :
users.sort(Comparator.comparing(User::getRank).reversed()); users.forEach(u -> System.out.println(u.getName() + " : " + u.getRank()));
متد sort را میتوان با تابعی static از کلاس Comparator به نام comparing مقدار دهی کنیم . میبینیم که ۷ خط کد تبدیل به یک خط شده است.
قابلیت دیگری که متد comparing به ما میدهد این است که اگر دو آیتم از نظر rank باهم برابر بودن , بتوان بر اساس فیلد دیگری آنها را دسته بندی کرد :
users.sort(Comparator.comparing(User::getRank).reversed().thenComparing(User::getName));
در اینجا اگر دو آیتم با rank های برابر باشند , بر اساس اسم آنها مرتب میشود.
تا بحال از enhanced for برای کار با تک تک اعضای یک لیست استفاده میشد ولی با متد list.forEach میتواند همین کار را انجام داد به این صورت :
users.forEach(u -> System.out.println(u.getName() + " : " + u.getRank()));
در پایان به کاربرد بسیار خوب lambda در view برنامه های میپردازیم . وقتی شما یک JButton طراحی میکنید حتما باید برای استفاده از آن به این صورت عمل شود :
jButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { } });
اما با lambda میتوان به این صورت عمل شود :
jButton.addActionListener(e-> System.out.println("hi zero to hero"));
همچنین lambda مقایسه بین مدل هارا نیز آسان کرده است . میخواهیم مدل هایی که rank اها بیشتر از ۱ است را از آنهایی که کمتر از ۱ است, متمایز کنیم .
Predicate<User> userPredicate = p -> p.getRank() > 1f; Predicate<User> negative = userPredicate.negate(); System.out.printf("good users : "); for (User user : users) { if (userPredicate.test(user)) { System.out.println(user.getName()); } } System.out.println("bad users : "); for (User user : users) { if (negative.test(user)) { System.out.println(user.getName()); } } }
البته میتوان یک لیست نیز با استفاده از این روش ساخت :
List<User> positive=users.stream().filter(userPredicate).collect(Collectors.toList());
میتوان rank کل مدل هارا باهم جمع کرد :
double sum = users.stream().mapToDouble(User::getRank).sum();
برای چاپ کردن اطلاعات یک مدل تا بحال از toString() استفاده میکردیم ولی lambda امکان ساده تری را فراهم کرده است. ابتدا متد زیر را به مدل اضافه میکنیم :
String printCustom(Function<User, String> userStringFunction) { return userStringFunction.apply(this); }
و برای استفاده از آن نیز میتوان به این صورت عمل کرد :
System.out.println(user.printCustom(u -> "Name : " + u.getName() + " - Rank :" + u.getRank()));
دیدگاهتان را بنویسید
برای نوشتن دیدگاه باید وارد بشوید.