Skip to content

Latest commit

 

History

History
187 lines (123 loc) · 5.28 KB

chapter-07.asc

File metadata and controls

187 lines (123 loc) · 5.28 KB

Method Reference

Java programlama dilinde metodlar, sınıfların içinde bulunan iş birimleridir.

Metodlara erişimin ise statik olup olmadığına göre iki erişim biçimi vardır. Statik metodlara sınıf üzerinden erişilebilirken, statik olmayan metodlara nesne üzerinden erişim sağlanabilmektedir.

Java 8 ile beraber metod birimleri, bir lambda ifadesine, dolayısıyla bir fonksiyonel arayüze karşılık olarak referans verilebilmektedir.

Lambda ifadeleri yazılırken, tek metoda sahip arayüzün (fonksiyonel arayüz) metod girdi ve çıktısı baz alınmaktadır. Eğer daha önce yazdığınız bir metodun girdi ve çıktısı, bir fonksiyonel arayüz metodunun girdi ve çıktısına birebir uyuyorsa, o metod bir lambda deyimi yerine kullanılabilmektedir.

Örneğin;

Consumer arayüzü T türünde tek bir parametre alır. Metod dönüşü void 'dir.

@FunctionalInterface
public interface Consumer<T> {

    void accept(T t); // t-> {}

}

Yukarıdaki Consumer arayüzü türünden bir nesneyi, e{} lambda deyimiyle oluşturabiliriz.

Consumer<String> consumerWithLambda = e-> {

};

Lambda ifadeleri yazarken metod girdi ve çıktısına odaklandığımıza göre, lambda deyimiyle birebir örtüşen metodları, lambda deyimleri yerine kullanabilir miyiz? Bunu aşağıdaki metod üzerinden düşünelim.

public void herhangiBirMetod(String e){

}

Yani herhangiBirMetod metodunun imzasıyla Consumer<String> arayüzünün accept metodunun imzası birbiriyle aynıdır. herhangiBirMetod, String türünden tek bir parametre almaktadır, metod dönüşü ise void 'dir. Bu uyum neticesinde eğer istenirse, bu metodun referansı ile Consumer<String> türünden bir nesne oluşturulabilir.

Bir metodu referans vermek

Java programlama dilinde bir metodun nasıl referans verileceği metodun statik olup olmadığına göre değişmektedir. Bir metodun referans olarak verilebilmesi için ise :: ikilisi kullanılır.

Statik metodlarda

Statik metodlar sınıfa ait bileşenlerdir. Bu yüzden erişim kurulurken dahili olduğu sınıf üzerinden erişim kurulur.

Örneğin;
Consumer<String> consumerWithMetRef = <ClassName>::herhangiBirMetod;
Statik olmayan metodlarda

Statik olmayan metodlar nesneye ait bileşenlerdir. Bu sebeple nesnenin referansı üzerinden erişilmelidirler.

Örneğin;
Consumer<String> consumerWithMetRef = <ObjectRef>::herhangiBirMetod;
Örnek 1

Şimdi birkaç örnek ile metod referansları deneyimleyelim. Aşağıda "Ali","Veli","Selami" verilerini içeren bir List nesnesi bulunmaktadır. Bu nesnenin ise, forEach isimli metodu bulunmaktadır. Bu nesnenin kabul ettiği parametre ise Consumer<String> türündendir.

List<String> names= Arrays.asList("Ali,Veli,Selami");

names.forEach(new Consumer<String>() { (1)
    @Override
    public void accept(String s) {
        System.out.println(s);
    }
});
  1. Sırayla konsole çıktılar.

Şimdi bu örneği Lambda ifadesiyle yeniden aşağıdaki gibi yazabiliriz.

List<String> names= Arrays.asList("Ali,Veli,Selami");

names.forEach(s->{
   System.out.println(s);
});

Lambda ifadesi, satır sayısı bazında kodu iyice kısalttı. Şimdi bu aynı işi metod referans kullanarak yapalım.

public class App{

    static List<String> names= Arrays.asList("Ali,Veli,Selami");

    // Statik metod
    public static void herhangiBirMetod(String s){
        System.out.println(s);
    }

    // Non-statik metod
    public void digerBirMetod(String s){
        System.out.println(s);
    }


    public static void main(String[] args){

        names.forEach(App::herhangiBirMetod); (1)

        // veya

        App app=new App();
        names.forEach(app::digerBirMetod); (2)

        // veya

        names.forEach(System.out::println); (3)
    }

}
  1. Statik metodu referans vermek

  2. Non-statik metodu referans vermek

  3. Diğer bir örnek

Örnek 2

Collections#sort metodu ile bir dizi nesneyi sıralamak istiyoruz diyelim. Bu sıralamayı, metodun 2. parametresinde Comparator türünden bir nesne ile kontrol edebiliriz.

List<Integer> numbers = Arrays.asList(5, 10, 1, 5, 6);

Collections.sort(numbers, new Comparator<Integer>() {
    @Override
    public int compare(Integer o1, Integer o2) {
        return o1 - o2;
    }
});
Note
Fonksiyonel olarak Comparator arayüzü ve java.util.BiFunction arayüzü birebir aynıdır.

Şimdi anonim olarak oluşturulan Comparator türünden nesneyi Lambda ifadeleriyle yeniden yazalım.

List<Integer> numbers = Arrays.asList(5, 10, 1, 5, 6);

Collections.sort(numbers, (o1, o2) -> o1 - o2)

Şimdi ise Lambda deyimi yerine metod referans kullanarak bu işi yapalım.

public Integer sirala(Integer o1, Integer o2){

    return o1 - o2;

}

public void birMetod(){

    List<Integer> numbers = Arrays.asList(5, 10, 1, 5, 6);

    Collections.sort(numbers, this::sirala); (1)
}
  1. Lambda yerine metod referansı

Metod referans kullanmak var olan iş mantığını kolay bir biçimde referans vermeye olanak sağlamaktadır.

Tekrar görüşmek dileğiyle.