دیروز که داشتم اتفاقی با کالکشنهای جاوا بازیبازی میکردم و متدهای جدیدشونو تمرین میکردم متوجه نکتهای تو Comparator شدم که قبلا حواسم بهش نبود و یهو مغزم ارور داد.
مشکل در ارجا متد توی Comparator بود. خب میدونستم که هرجا که ورودی و خروجی متدی که قراره پیاده کنیم با متدی که قبلا نوشتیم برابر بود میتونیم از Method Reference استفاده کنیم و متدی که وجود دارد رو به جای لامبدا یا کلاس بینام استفاده کنیم. اما در سناریویی که الان میگم امضا یا همون signature متدی که پاس میدیم با لامبدا معادل اون نمیخونه!!!
سناریو سادس یک لیست مثل زیر داریم که با آبجکت های کلاس Person پر شدن. کلاس Person تنها یک فیلد به نام name دارد همراه با getter و setter و یک سازنده که با دریافت name کار میکنه :
List<Person> people = new LinkedList<>(); people.add(new Person("Bita")); people.add(new Person("Parsa")); people.add(new Person("Ali"));
خب حالا میخوایم این لیست رو مرتب کنیم برای اینکار به راحتی میتونیم از متد جدید واسط Comparator استفاده کنیم که comparing باشه :
people.sort( Comparator.comparing( Person::getName ) );
دقیقا نکته اینجاست متد comparing یک function به عنوان ورودی میگیره و ما باید متد apply رو پیاده سازی کنیم که متدی است با یک ورودی. بیاید معادل لامبدا مثال بالا رو باهم ببینیم :
(Person p) -> p.getName();
خب همینطور که میبینید ما یک ورودی داریم اما در عبارت ارجا که نوشتیم getName ورودی نداره!!!
پس چجوری match میشه؟
جواب اینه که وقتی جاوا میبینه که نوع آبجکتی که در ورودی هست با کلاسی که شما دارین بهش رفرنس میدید (Person) یکیه و متد به اون آبجکت نیاز داره برای اجرا خودش اونو پاس میده و امضا متد رو درست در نظر میگیره.
یعنی عبارت Person::getName همون ()p.getName ترجمه میشه. اما مثلا اگر بنویسیم OtherClass::getName ارور میگیریم چون نوع ورودی ما Person است و با OtherClass فرق میکنه پس match نمیشه.
عنوان این نوع ارجا اگر خواستید سرچ کنید اینه :
Reference to an instance method of an arbitrary object of a particular type
در عنوان بالا arbitrary object منظور همون ورودیه که در لامبدا هست اینجا (Person p)
امیدوارم کمک کرده باشم خوشحال میشم توی توئیترم بیشتر معاشرت کنیم تا بعد :)